I am developing an ember-cli project and I am working on a system that allows me to resolve templates that have not been loaded and may possibly live outside of the project structure.
I would like to have a folder in my dist/assets directory called templates and inside that folder would be all the pre compiled templates from app/templates/external. This is my current Brocfile.js attempt with broccoli stew
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var stew = require("broccoli-stew");
var app = new EmberApp({
vendorFiles: {
"jquery.js": null
},
sassOptions: {
includePaths: [
'bower_components/bourbon/app/assets/stylesheets/',
'bower_components/neat/app/assets/stylesheets/',
'bower_components/bitters/app/assets/stylesheets/'
]
}
});
var additionalTrees = [];
var templateFiles = stew.find(appTree, "assets/app/templates/external");
templateFiles = stew.mv(templateFiles, "assets/app/templates/external", "assets/templates");
additionalTrees.push(templateFiles);
module.exports = app.toTree(additionalTrees);
There is npm package called broccoli-file-mover , easy to use , and can be found here
The usage is very simple , as easy as :
moveFile(inputTree, options)
can be used to move files ( multiple , or single ) , or whole folders
Example :
Moving a single file from app/main to app:
var moveFile = require('broccoli-file-mover');
var tree = moveFile('app', {
srcFile: 'app/main.js',
destFile: '/app.js'
});
Moving app/main to app and test/main to test:
var moveFile = require('broccoli-file-mover');
var tree = moveFile('app', {
files: {
'app/main.js': 'app.js',
'test/main.js': 'test.js'
}
});
Also , prior to blessnm comment broccoli funnel is a possible solution , as you can copy your directory to wherever you want ( thought the question states moving , but thought copying might be an acceptable solution ) , here is the repo of the plugin.
Related
I have an addon which needs to copy a set of JS files from their bower directory to the Ember app's root of /dist (this is for scoping rules associated with service workers). I thought maybe I could use the treeForApp hook but while I'm getting no errors I'm also not getting the desired result.
The index.js is:
const Funnel = require('broccoli-funnel');
module.exports = {
name: 'ember-upup',
treeForApp: function(tree) {
tree = new Funnel(tree, { include:
[
'bower_components/upup/dist/upup.min.js',
'bower_components/upup/dist/upup.sw.min.js'
]});
return this._super.treeForApp.call(this, tree);
},
Note: I thought I might be able to solve this problem by simply copying the javascript files as part of index.js postBuild hook but while this DOES put the JS files into the dist folder's root it is not served by ember-cli's ember serve apparently if not pushed through one of it's build pipelines.
Stefan Penner has now pointed out the the dist directory is for developers to look at but serving is actually done within the tmp directory structure ... this explains why my "hack" didn't work.
It looks like my initial attempt wasn't entirely far off. To make it work you need to hook into the treeForPublic hook like so:
const path = require('path');
const Funnel = require('broccoli-funnel');
const mergeTrees = require('broccoli-merge-trees');
const JS_FILES = ['upup.min.js', 'upup.sw.min.js'];
module.exports = {
treeForPublic: function() {
const upupPath = path.join(this.app.bowerDirectory, 'upup/dist');
const publicTree = this._super.treeForPublic.apply(this, arguments);
const trees = [];
if (publicTree) {
trees.push(publicTree);
}
trees.push(new Funnel(upupPath, {
include: JS_FILES,
destDir: '/'
}));
return mergeTrees(trees);
}
}
Hope that helps.
I'm trying to use ember cli with sass, so i installed the ember-cli-sass, and i'm trying to configure like this:
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var emberCLIBuild = function(defaults) {
var app = new EmberApp(defaults, {
sassOptions: {
includePaths: [
'app/styles/admin/main.scss',
'app/styles/site/main.scss'
]
}
});
return app.toTree();
};
module.exports = emberCLIBuild;
but, when i try to run ember serve, the terminal will throw an error:
ENOTDIR: not a directory, scandir '/Users/xxxx/DEV/PubCrawl/Site/tmp/sass_compiler-input_base_path-55sPHD0L.tmp/1/'
How could i fix this? I don't see the problem.
Thanks.
According the demo on the github page, it looks like it takes paths, not file names (which makes sense since it's called includePaths). I think you want:
includePaths: [
'app/styles/admin',
'app/styles/site'
]
I am trying to make my addon supply vendor'd data to the app using it. The library is CKEditor (a customized version generated from the CKEditor builder).
I know I can use the addon blueprint to add a bower dependency but since CKEditor is customized I can't use bower to download that same version in the consuming app.
I've used the treeForPublic and broccoli funnel to copy from my addon vendor folder the whole ckeditor folder to the app public folder (this is required by ckeditor).
My only issue is that the consuming app also needs to have the ckeditor folder in its vendor folder or it won't build because the watcher can't find it.
I was with the impression that if the addon was moving the folder to the public destination and was also importing js/css files in the included hook the original vendor'd folder was not needed by the final app.
Have I understood it wrong or can I do this without duplicating my ckeditor folder between the addon and the app ?
here is what I have so far :
included: function(app) {
this._super.included(app);
app.import('vendor/ckeditor_custom/ckeditor.js');
app.import('vendor/ckeditor_custom/styles.js');
app.import('vendor/ckeditor_custom/lang/fr.js');
app.import('vendor/ckeditor_custom/skins/minimalist/editor.css');
},
contentFor: function(type, config) {
if (type === 'vendor-prefix') {
return "window.CKEDITOR_BASEPATH = 'assets/ckeditor/';";
}
},
treeForPublic: function (tree) {
var ckeditorTree = new Funnel('vendor/ckeditor_custom/', {
srcDir: '/',
exclude: ['**/.DS_Store','**/*.md'],
destDir: 'assets/ckeditor'
});
return BroccoliMergeTrees([tree, ckeditorTree]);
},
treeForVendor: function (tree) {
var ckeditorTree = new Funnel('vendor/ckeditor_custom/', {
srcDir: '/',
exclude: ['**/.DS_Store','**/*.md'],
destDir: 'ckeditor_custom'
});
return ckeditorTree;
},
Thanks for the help!
Give this a whirl:
var path = require('path');
var mergeTrees = require('broccoli-merge-trees');
var concat = require('broccoli-concat');
module.exports = {
name: 'myaddon',
treeForVendor: function(tree) {
var trees = [tree];
var ckeditorTree = path.join('bower_components', 'ckeditor_custom');
trees.push(concat(ckeditorTree, {
inputFiles: [
'ckeditor.js',
'styles.js',
'lang/fr.js'
],
outputFile: '/ckeditor.js'
}));
trees.push(concat(ckeditorTree, {
inputFiles: [
'skins/minimalist/editor.css'
],
outputFile: '/ckeditor.css'
}));
return mergeTrees(trees);
},
included: function included(app) {
this.app = app;
app.import('vendor/ckeditor.js');
app.import('vendor/ckeditor.css');
}
};
I have an ember-cli based app which needs to be integrated into an existing java/JSP app. For this to happen I need to generate a JSP file with js/css fingerprinted URLs which are generated by ember-cli/broccoli-asset-rev.
This is working fine for a html file and I can set it use a JSP file by changing my Brocfile.js to include:
var app = new EmberApp({
outputPaths: {
app : {
html: 'index.jsp'
}
}
});
but this prevents ember serve working as it uses the index.jsp as the html file. Is it possible to have both generated?
After trying many things I have come up with two solutions, both have drawbacks. The first is to use make a new broccoli tree and merge it with he app tree then explicity run broccoli-asset-rev on the resulting tree. The downside of this is that the mustache does not get hydrated, this is useful for outputting config. This would look something like:
//Brocfile.js
var mergeTrees = require('broccoli-merge-trees');
var funnel = require('broccoli-funnel');
var assetRev = require('broccoli-asset-rev');
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var jspTree;
var app = new EmberApp({
fingerprint: {
enabled: false
},
storeConfigInMeta: false
});
jspTree = funnel('app', {
files: ['index.jsp']
});
module.exports = assetRev(mergeTrees([appTree = app.toTree(), jspTree]), {
extensions: ['js', 'css'],
replaceExtensions: ['jsp', 'html']
});
The other solution is the override a private api method in ember-cli which builds the tree for the index. This solution does let the mustache get hydrated but relies on a private method. You can find details here and here
How about adding symbolic link?
ln -s index.jsp index.html
Depending on what build tool you're using in your project, I'd probably recommend something like the following:
Put some placeholder sections in your index.html.
Copy index.jsp to index.jsp.tmp.
Copy in code from index.jsp into your placeholder sections.
Move index.jsp.tmp back to index.jsp and clean up.
You might consider something like gulp-replace to do the work.
In an Ember-CLI project, if I add a directory containing webfonts and their CSS stylesheets to the public/assets directory, I can use them with something like #import 'assets/font/regular/stylesheet.css. This works fine.
Ideally though, I'd like to keep these assets out my git repository, and instead bower install them as client-side dependencies, but how can these assets be used in the Ember-CLI build?
The documentation mentions app.import(FILE) in Brocfile.js, which works for CSS stylesheets, but not for a WOFF font file:
$ ember build
version: 0.0.28
Build failed.
Error: Path or pattern "nicefont.woff" did not match any files
at Object.multiGlob (/(PATH)/node_modules/ember-cli/node_modules/broccoli-static-compiler/node_modules/broccoli-kitchen-sink-helpers/index.js:216:13)
at /(PATH)/demo/node_modules/ember-cli/node_modules/broccoli-static-compiler/index.js:25:27
at invokeCallback (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/promise.js:228:21)
at publish (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/promise.js:176:9)
at publishFulfillment (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/promise.js:312:5)
at flush (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/asap.js:41:9)
Also, I would like to specify a directory, which is app.import() refuses.
Is there an Ember-CLI / Brocolli way of doing this?
I thought I was stuck on this issue, but apparently a cup of tea and explicitly phrasing the question on StackOverflow pushed me in the right direction…
If you install a client-side dependency with bower, then in an Ember-CLI project these will end up in vendor/. To use (parts of) them without changing them, we can use Broccoli's slightly awkwardly named broccoli-static-compiler. First, install two build-time dependencies:
npm install --save-dev broccoli-static-compiler
npm install --save-dev broccoli-merge-trees
In Brocfile.js add at the top below the EmberApp import:
var mergeTrees = require('broccoli-merge-trees');
var pickFiles = require('broccoli-static-compiler');
And at the bottom of Brocfile.js:
// Remove this line:
// module.exports = app.toTree()
// Copy only the relevant files:
var fontOpenSans = pickFiles('vendor/font-opensans', {
srcDir: '/',
files: ['**/*.woff', '**/stylesheet.css'],
destDir: '/assets/fonts'
});
// Merge the app tree and our new font assets.
module.exports = mergeTrees([app.toTree(), fontOpenSans]);
Here our client-side dependency is a font-opensans, which refers to a local git repository containing a copy of the Open Sans webfont.
That is all! To use the web-font, link to assets/ from index.html:
<link rel="stylesheet" href="assets/fonts/opensans_regular/stylesheet.css">
This was tested with ember-cli 0.0.40 and a few earlier versions.
The supported answers are a bit out of date. At the time of this writing Ember CLI 0.2.2, there is support for directly copying/fingerprinting vendor folders you want in your assets directory.
// Brocfile.js
var app = new EmberApp();
...
var extraAssets = new Funnel('bower_components/a-lovely-webfont', {
srcDir: '/',
include: ['**/*.woff', '**/stylesheet.css'],
destDir: '/assets/fonts'
});
module.exports = app.toTree(extraAssets);
Documentation here
Similar to answer from JeroenHoek, in ember-cli, version 0.0.40, I ended up doing it right under the app.import before module.exports. I use the augmentation pattern to encapsulate what I'm trying to do so that when/if it's no longer necessary, or there is a more preferred way to do it, I can clean it up easily, and remove modules that aren't used anymore.
/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var app = new EmberApp();
// Use `app.import` to add additional libraries to the generated
// output files.
//
// ... [comments omitted]
app.import('vendor/moment/moment.js');
var tree = app.toTree();
tree = (function mergeFontAwesomeTree(tree) {
var mergeTrees = require('broccoli-merge-trees');
var pickFiles = require('broccoli-static-compiler');
var fontawesome = pickFiles('vendor/fontawesome/fonts', {
srcDir: '/',
destDir: '/fonts'
});
return mergeTrees([tree, fontawesome]);
})(tree);
module.exports = tree;