Sharing a public tree in an ember-cli addon - ember-cli

I am completely puzzled when I read all the information I can gather about sharing a public assets directory from an ember-cli addon.
Is there anybody having it working around here? Any ref to an example addon doing it would also be appreciated...

So... I finally found a way to share the static assets:
- I placed the files in vendor/assets directory
- Declared the files to shared (each file...) into the addon's index.js file # addon's root
app.import('vendor/assets/my_image.png');
An interesting option of app.import statement I found in my searches is destDir, which allows to customize the target publication path of the asset:
app.import('vendor/assets/a/b/c/my_image.png', { destDir: 'x/y' });
will publish my_image.png # URL /assets/x/y/my_image.png
Hoping this will help others to save time...

Assets of addons are available under a namespace. For example if there is a file in public/assets/image.png in your addon, this file is available under /my-addon/assets/image.png.
If you don't want to use a namespace, you can overwrite the treeForPublic hook in the addon definition as demonstrated in this gist:
const Funnel = require('broccoli-funnel');
const mergeTrees = require('broccoli-merge-trees');
module.exports = {
name: require('./package').name,
treeForPublic: function(tree) {
const assetsTree = new Funnel('public');
return mergeTrees([tree, assetsTree], {
overwrite: true,
});
},
};

Related

Requiring config.js file in VSCode extension with absolute path (e.g. "C:\...") does not work

I am developing the Argdown VSCode extension. The Argdown parser can be configured using either argdown.config.json files or argdown.config.js files exporting a config object. Using Javascript files is the easiest way to allow users to add custom plugins to the Argdown parser.
If the user tells the parser to use a Javascript file, the file is loaded using import-fresh, (which uses node's require, but deletes the cached version.
Using the Argdown commandline tool (#argdown/cli) this works fine, but in the VSCode extension the module of the config file can not be found. The extension is using absolute file paths to require the config module (e.g. "C:\Users\my-username\projects\my-argdown-project\argdown.config.js"). These paths work with import-fresh outside of the VScode extension.
Is there a security restriction for VSCode extensions that does not allow to require modules with absolute file paths? Or is there some other reason why this does not work?
This was not related to VSCode. The problem was caused by bundling up import-fresh with webpack. I thought that webpack would ignore dynamic imports, but it did not.
I was lucky: Since last month, webpack supports "magic comments" for require (not only for import). So I can use:
require(/* webpackIgnore: true */ file);
You have to activate magic comments support in your webpack config:
module.exports = {
parser: {
javascript: {
commonjsMagicComments: true,
},
},
}
Now the next question is how to add the magic comments to the import-fresh package. For that I used the string-replace-loader:
module.exports = {
module: {
rules: {
{
enforce: "pre",
test: /import-fresh[\/\\]index\.js/,
loader: "string-replace-loader",
options: {
search:
"return parent === undefined ? require(filePath) : parent.require(filePath);",
replace:
"return parent === undefined ? require(/* webpackIgnore: true */ filePath) : parent.require(/* webpackIgnore: true */ filePath);",
},
},
}
}
}
After that, I could load the argdown.config.js files again, even after bundling everything with webpack.

prefix assets for production with static path

for assets such as /assets/image.png, that I call in stylesheets, javascript etc...
I need to prefix or prepend a path to server.
so that /assets/image.png becomes /static/ember/memory/dist/assets/image.png for production.
where it will be served as ie: http://domain.com/static/ember/memory/dist/assets/image.png
i need to pass and use a STATIC_PATH variable when compiled/built for production that will be prefixed, or compile it so that it does it automatically.
I have checked ember-cli docs for assets compilation:
var app = new EmberApp({
fingerprint: {
prepend: '/static/ember/memory/dist/'
}
});
however, this doesn't work as where the assets are being called the path doesn't change in production, unless it actually modified the path where it's called.
for example in styles.css if I call /assets/image.png somewhere, I need to prefix this with STATIC_PATH + /assets/image.png when in production.
the STATIC_PATH will look something like:
/static/ember/memory/dist/
I can add this manually for production in development, but then cannot test in development.
thanks for any response.
You can pass a prepend option in the ember-cli-build file, you will have to exclude the assets that don't need the path:
var app = new EmberApp({
fingerprint: {
exclude: ['excludedAssets/'],
prepend: '/static/ember/memory/dist/'
}
});
For more information check out asset compilation

How to redirect assets to public, make public invisible and make lessMiddleware work

Yesterday I had a public folder with generated css, and a source folder with less
root
/public
/css
/source
/less
and a less middleware like this
module.exports = function (app, dir) {
return lessMiddleware(path.join(dir, 'source', 'less'), {
dest: path.join(dir),
preprocess: {
path: function(pathname, req) {
return pathname.replace('public' + path.sep + 'css' + path.sep, '');
}
}
});
};
It works fine, except that root dir is open, and I can get access to public folder. So, I put a NGINX as proxy, and had no problems, it denies access to root folder and redirects 'assets' to 'public'.
So I had url's like http://localhost/assets/css/main.css
Today I want to get rid of nginx for debug purposes. So I give static access to assets folder like this
if (settings.debug) {
app.use('/assets', express.static(path.join(__dirname, "public")));
}
The problem is that less middleware stopped working, because this code changes path for middleware to
c:\node\myproject\source\less\assets\css\main.less
Is there a way to redirect 'assets' to 'public' using express js standard static middleware? Or a standard way to substitute '/assets' with '/public' and pass this request forth?
I can do that with app.get(... and parse request and so on. I also can change middleware 'preprocess' directive. But I want to spend as less code as possible.
P.S.
Ok, now I can make assets work
if (settings.debug) {
app.use(function(req, res, next) {
if (req.url.indexOf('/assets/') === 0) {
req.url = req.url.replace('/assets/', '/public/');
}
next();
});
}
app.use(require('./config/lessMiddlewareConfig.js')(__dirname));
app.use('/public', express.static(path.join(__dirname, 'public')));
but I want to deny access to public now.
On your server is it actually necessary to use less middleware?
I got around this, buy adding this to my deployment shell script:
curl http://localhost:3000/stylesheets/style.css > /dev/null
which forces a recompile by requesting the css file directly to the node process.

sails.js Is it possible to set process.env variables from application?

I am trying to use npm module fb to use facebook api. The config file is located in the module and here is the snapshot of the same
var config = { };
// should end in /
config.rootUrl = process.env.ROOT_URL || 'http://localhost:3000/';
config.facebook = {
appId: process.env.FACEBOOK_APPID || '130243393813697',
appSecret: process.env.FACEBOOK_APPSECRET || 'c82696768ae4ad8b63db874cb64eb558',
appNamespace: process.env.FACEBOOK_APPNAMESPACE || 'nodescrumptious',
redirectUri: process.env.FACEBOOK_REDIRECTURI || config.rootUrl + 'login/callback'
};
module.exports = config;
I don't wish to change the config file of the module since node_modules folder is kept in the gitignore list. For configuring the module to use my app's appId and appSecret, I need to set the process.env variables FACEBOOK_APPID and FACEBOOK_APPSECRET
I understand that it can be done while calling the sails lift but is it by any means possible to set these values inside the app so that I only have to call
sails lift
without any of those variables and those should be set automatically ? Or what is the best way to achieve what I am trying to do here ?
You should set the environment-variables outside of your App.
Instead of sails lift you could also use node app.js. With that you can define environment-variables for your node-application with:
$> FOO='bar' node app.js
In your case:
$> FACEBOOK_APPID='232322a22' FACEBOOK_APPSECRET='mysecrete' node app.js
If you want to set this vars in your app (I wouldn't suggest that!) you could set them before including your npm-module. For example in your config/bootstrap.js:
module.exports.bootstrap = function(cb) {
process.env.FACEBOOK_APPID = "myvar";
process.env.FACEBOOK_APPSECRET = "mysecrete";
sails.facebook = require("yourmodule");
cb();
};
Here is a good link for setting environment variables when "Production", "Staging" and "Development" in Sails feels fragmented.
Here is a quick video tutorial which simply explains how to create environment variables in node.js
Step1:
Install the package dotenv as dependency
$ npm install dotenv --save
Step2:
Then require dotenv in app.js and load the .env file
var dotenv = require('dotenv');
dotenv.load();
Step3:
Create a .env file in the root folder (ie. at the same document level as app.js file)
Step4:
Add your environment variables
S3_KEY=enfiownqefniqofewqofnieqwvewlk
S3_SECRET=123456789
Now you can access those environment variables anywhere in the app (probably in some config/ files):
return {
key: process.env.S3_KEY,
secret: process.env.S3_SECRET,
region: 's3-eu-west-1',
bucket: 'myBucket',
s3params: {
ACL: 'public-read'
}
}
Credit goes to Noah Bass for providing this tutorial.

django-tastypie-swagger not serving Swagger's JS/CSS files

I have a fresh install of django-tastypie and django-tastypie-swagger.
http://localhost:8000/tasty/doc/ serves the necessary HTML, but doesn't pull in any of the CSS or JS that's needed to make it work.
http://localhost:8000/tasty/doc/resources/ works and shows:
{
basePath: "http://localhost:8000/tasty/doc/schema/",
apis: [
{
path: "/snap"
},
{
path: "/user"
}
],
apiVersion: "0.1",
swaggerVersion: "1.1"
}
But all the others (/schema/ and the static files) return 404 errors.
I had the same problem you had and solved it by creating a file under my project templates directory on the following path: templates/tastypie_swagger with the content of this file:
Note that the problem is caused by the STATIC_URL variable, which is misunderstood, I replaced that variable with my project url, and it worked perfect.
For anyone who encounter this problem in the future ... you might want to perform the following command after installing django-tastypie
python manage.py collectstatic --noinput
I had the same problem. Simple fix add 'django.core.context_processors.static' to 'context_processors' in settings.py. Than STATIC_URL will work.