I have got a theme from themeforest which has a plugins/ directory with 20-30 directories inside that with js/ and css/ folders.
So I need to have a folder outside of the default sails js/ and styles/ called plugins/, which will then be included in the grunt build.
I tried to copy the usual jsFilesToInject and replicate it all with this:
var plugInJSFilesToInject = [
// All of the rest of your client-side js files
// will be injected here in no particular order.
'plugins/**/*.js'
];
Then specifing it in the sails-linker:devJs like so:
devJs: {
options: {
startTag: '<!--SCRIPTS-->',
endTag: '<!--SCRIPTS END-->',
fileTmpl: '<script src="%s"></script>',
appRoot: '.tmp/public'
},
files: {
'.tmp/public/**/*.html': require('../pipeline').jsFilesToInject,
'views/**/*.html': require('../pipeline').jsFilesToInject,
'views/**/*.ejs': require('../pipeline').jsFilesToInject,
'.tmp/public/**/*.html': require('../pipeline').plugInJSFilesToInject,
'views/**/*.html': require('../pipeline').plugInJSFilesToInject,
'views/**/*.ejs': require('../pipeline').plugInJSFilesToInject
}
},
And recieved this error when running sails lift:
------------------------------------------------------------------------
Aborted due to warnings.
Running "sails-linker:devJs" (sails-linker) task
Warning: Cannot read property 'indexOf' of undefined
This also needs to be done for a css/ directory, which is why I definitely need to have it outside of the js/ or styles directory.
I ended up just placing the plugins/ in the same jsFilesToInject array, because there is no reason why it can't go in there:
var plugInJSFilesToInject = [
// All of the rest of your client-side js files
// will be injected here in no particular order.
'js/**/*.js',
// Plugins go here
'plugins/**/*.js'
];
Related
I am trying to use the Webpack's IngorePlugin. I am using my Webpack file only to create a CSS file. On build, it outputs a JS file. But I don't want that. Tried ignoring JS files but still outputs it.
new webpack.IgnorePlugin(/^\.\/js\/(?!admin)/),
Outputs in the ROOT folder. So I want to disable all JS files from the output in the root folder. "admin" is the file being created.
How can I do this?
To properly answer your question, it'd be helpful if you posted a link to the full WP config file and an example of the file that's being processed.
Also, you mentioned you're only using WP to create a CSS file, does that mean you're just trying to use something like SASS, Stylus, Less, etc? If so, you could probably just set up a package.json script to compile your CSS without WP.
For example, if you have a .scss file, you could install node-sass, and create a simple Node script to compile what file you pass in as an arg.
bin/
- build-css.js
src/
- styles.sass
Within build-css.js
#!/usr/bin/env node
const { basename, resolve } = require('path');
const sass = require('node-sass');
const [...files] = process.argv.slice(2);
if (files.length) {
files.forEach((relativeFilePath) => {
const fileName = basename(relativeFilePath, '.scss');
sass.render(
{
file: resolve(__dirname, relativeFilePath),
outFile: resolve(__dirname, `./public/css/${fileName}.css`),
},
(err, result) => { console.log(err); }
);
});
}
else {
console.log('No files were provided to process');
}
Within package.json
"scripts": {
"build:css": "node ./bin/build-css.js"
}
The above has the benefit of giving you the control of how your files are processed at a more granular level, and you're only locked in to any SCSS changes, instead of Webpack and SCSS.
If you're using WP for it's file watching capabilities, you could instead wire up chokidar to run the new script when you change files.
We load files dynamically i.e., we don't know which files will be loaded until runtime. At the same, for faster loading, we'd like to put related files in the same chunk.
How can I do that with webpack?
This is what we have and it's failing with a 404 error (1.1.bundle.js not found)
This is what webpack.config looks like:
entry: {
main: //...,
related_files: [ //should create chunk for file1 and file2?
'./file1.js',
'./file2.js'
]
},
This is what the code to dynamically load the files looks like:
var dynamicFileName = //...
require.ensure([], function (require) {
//should dynamically load the chunk containing dynamicFileName?
//fails with 'file1.js' or 'file2.js'
var modImpl = require(dynamicFileName);
//...
});
Update 1: the error message is caused by not configuring output.publicPath. However, I never created 1.1.bundle.js. It seems to be ignoring the entry point.
Update 2: even after fixing output.publicPath, it's unable to load a dynamically generated filename. So it seems that webpack cannot handle this.
By default, webpack tries to bundle all the code in a single file. If you're using code from file1.js/file2.js in main entry point, webpack will bundle contents of all the files in main.js, and second entry point related_files will output only file1/file2 contents.
Webpack handles this situation by using CommonsChunkPlugin, your config must look like this:
entry: {
main: //...,
related_files: ['./file1.js','./file2.js']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('related_files', 'related_files.js')
]
Second part of the question is that webpack parses require statement, and outputs 1.1.bundle.js - the dynamic module, that can be loaded with require in the code. In your case, dynamicFileName = 'related_files', not file1/file2.
Please see http://webpack.github.io/docs/code-splitting.html#split-app-and-vendor-code
Is there any way to create Grunt task for Browserify to use fallback path?
Eg.
require('./module.js)
Check if module.js is in current directory, if not there, check some other directory?
project1
|- dir1
|- mod1.js - has: require('./mod2.js')
|- bundle.js - has: require('./mod1.js') and require('./mod2.js')
project2
|- dir2
|- mod1.js
|- mod2.js
I already tried remapify, but it can only check one specific directory.
And I don't want to change require paths inside modules, everything should be done trough Grunt.
I want to override some app (dir2), so I want to get (copy to dir1) only modules which I need to change, and to leave all others in app directory.
Gruntfile is in project1. Modules are CommonJS. I'm using grunt-browserify.
I know this is a little old now but it would be good to have an answer.
So, I asked myself a very similar question a couple of days ago and ended up doing basically what you want to do.
Using browserifyOptions from grunt-browserify like:
// Using grunt-browserify
grunt.loadNpmTasks("grunt-browserify");
grunt.initConfig({
browserify : {
options : {
browserifyOptions : {
// keep in mind that paths are relative to Gruntfile.js
paths: ["./first/path", "./second/path", "./and/so/on"]
}
},
dist : {
files: { "./path/to/dist.js" : "./path/to/src.js" }
}
},
});
And you will now be able to do:
var myModule = require("myModule");
opts.paths is an array of directories that browserify searches when
looking for modules which are not referenced using relative path. Can
be absolute or relative to basedir. Equivalent of setting NODE_PATH
environmental variable when calling browserify command. - Browserify
Theoretically, it should follow the paths in order, the only problem I've had is that it looks through native node modules (util, fs, etc..) before even searching those paths.
What the quote is saying is that if you do:
var myModule = require("./myModule");
Browserify will look for the module following the relative path. When you remove the relative path:
var myModule = require("myModule");
it can search through the stablished paths in the options.
Edit
I tested this and it works as expected. I have a module called myModule.js that is in "./current/directory", and I also have a module called myModule.js that is in "./modules/directory". Also, in current directory, I have the "src.js" that requires the module: require("myModule");. It looks in order through the paths and the first found is the one injected into bundle.js in this case.
grunt.initConfig({
browserify : {
dist : {
options : {
browserifyOptions : {
// keep in mind that paths are relative to Gruntfile.js
paths: ["./current/directory", "./modules/directory"]
}
},
files: { "./current/directory/bundle.js" : "./current/directory/src.js" }
}
},
});
Project Intro
My project is a single page storefront. The project has multiple modules, and each module contains a set of controller.js, view.js and model.js files, as well as a template.html file. And uses requirejs to manage dependencies.
Problem Statement
I want to use mainConfigFile to provide paths to reference modules in grunt-requirejs.
Part of my mainConfigFile's require.config is stored in separate file (base.dependency.config), and require.config.paths are pieced together by underscore at runtime.
base.dependency.config
config = {
baseDependencyConfig: {
paths: { ... }
shim: { ... }
}
}
main.js
var dependencies = config.baseDependencyConfig;
var basePaths = config.baseDependencyConfig.paths;
var extensionPaths = {
// extra sets of paths
};
// combine base paths and extension paths at runtime using underscore
var dependencyPaths = _.extend(basePaths, extensionPaths);
dependencies.paths = dependencyPaths;
require.config(dependencies);
// application startup
require(['app', 'eventbus']) {
// code
}
Error
However, grunt requirejs is ignoring mainConfigFile, grunt requirejs tries to find 'app.js' under root, when in fact, 'app' is defined under require.config paths as
'app': 'modules/base/app/base.app.controller'
my gruntFile:
module.exports = function (grunt) {
grunt.initConfig({
// ... other plugin config
requirejs: {
options: {
baseUrl: 'public',
// the paths for the named modules such as 'app' are defined
// in main.js under require.config paths
name: 'main',
include: [
'app',
'cart',
'category'
],
out: 'public/build/app-optimized.js',
mainConfigFile: 'public/main.js',
findNestedDependencies: true,
optimizeCss: 'none',
cssImportIgnore: 'style/style.css, style/mocha.css',
}
}
})
}
my file structure
public
|--modules/
| |--base/
| | |--cart
| | |--category
| | |--category.controller.js
| | |--category.view.js
| | |--category.model.js
| | └-category.template.html
| |
| └--extension/
|
|--style/
|--image/
|--main.js <-- main config file
|--other .js files
mainConfigFile, main.js lives in root, along with a few other application startup js files
main bulk of application files lives inside modules folder
each module folder contains its controller, view and model js file, as well as a template.html file
Edit
the gruntFile worked before, with different mainConfigFile (main.js) setup:
require.config({
paths: {...}
shim: {...}
})
// application startup
require(['app', 'eventbus']) {
// code
}
r.js uses Esprima as Javascript parser to extract the config object from the specified mainConfigFile. It only looks for certain signatures in the code.
Look at
hasRequire(): determine the AST node is a configuration call candidate
findConfig(): calls the above deciding how to extract the config
I've created a patch making it aware of recognizing
requirejs.config(_VariableToExport = { ... });
This is limited and the Javascript parser approach makes it very complicated to make r.js able to extract configurations that were created by functions (like in your code) or so. This patch has not been submitted to the project yet. I'm struggling with bureaucracy yet.
I think the only working workaround so far is
not to use mainConfigFile
exporting the config as NodeJS module
requiring the main.js/config.js in Node (Grunt)
passing the object as value to the config attribute or method
See my comment to this issue for a scribble.
This approach is proven in another, a bit older project I'm working on.
Related to r.js 2.1.11.
Not sure if I'm missing something but I have the following grunt setup for grunt-contrib-copy tasks.
copy: {
build: {
files: {
"server-dist/": "server/**/*.!(coffee)",
"client-dist/": "client/**/*.!(coffee)"
}
}
}
The client-dist copies as I expect recursively running through the file tree but the server-dist all sub-folders get flattened to the base folder. Any ideas why this is happening? Here is the i/o
server/
views/
errors/
404.jade
layouts/
base.jade
becomes
server/
errors/
layouts/
base.jade
the views folder gets completely blown out. One more thing...when I removed !(coffee) it works but I need to exclude coffee files since I have a grunt-coffee watch task running.
A followup to zacks comment:
copy: {
mytask: {
files: [
{expand:true, cwd:'dev-js/abc/', dest:'js/test/', src:['def.js']}
]
}
}
This copies the file ./dev-js/abc/def.js to ./js/test/def.js - at least on my 0.4.1 version. Zacks comment and the link included was very helpful, especially the fact, that basePath has been replaced.
Apparently the grunt-contrib-copy task has a sophisticated logic that's trying to automatically detect the base directory for copying source files (see related issue)
The solution is to explicitly specify the basePath option:
copy: {
build: {
files: {
"server-dist/": "server/**/*!(.coffee)"
},
options: {
basePath: 'server' // base directory in the source path
}
}
}
P.S. I'm not sure, however, why removing !(.coffee) changes the behaviour for you. I tried the same on my local machine and get the same results when specifying "server/**/*" instead of "server/**/*.!(coffee)" (i.e. the views folder is skipped)