Grunt babel multiple files and preserve source mapping - javascript

I am trying, using grunt and babel, to transpile all js6 files in a folder and end up with a concatenated single file (js5) with a working sourcemap to the original es6 files. However the sourcemapping does not work. My babel, concat settings below:
"babel": {
options: {
sourceMap : true
},
dist: {
files:[
{
expand: true,
cwd: 'wwwroot/js/src',
src: ['*.js'],
dest: 'tmp/js'
}]
}
},
concat: {
options: {
sourceMap: true
},
js: {
src: [
'tmp/js/*.js',
],
dest: 'wwwroot/js/app.js'
}
}
Versions:
"grunt": "0.4.5",
"grunt-bower-task": "0.4.0",
"grunt-babel": "5.0.1",
"grunt-contrib-concat" : "0.5.1"
I am ending up with firstly a folder with a lot of js files and src maps(tmp directory). But concatinating them into one file messes up with source mapping completely.
Ideas? Also, can I somehow skip the making of temporary files and sort of just pipe the result into concat?

Reversing the order of task will make this much easier.First run the concat task on the JS files. After that run babel task on the single file created by concat task previously with the following options
options: {
sourceMap: true,
inputSourceMap: grunt.file.readJSON('script.js.map')
},
Here the script.js.map file is the name of the source map file generated by concat task. As inputSourceMap option excepts a source map object , we pass it in using the grunt.file API's readJSON method
The full Grunt file configuration would be:
concat: {
options: {
sourceMap: true
},
js: {
src: ['Modules/**/js/*.js'],
dest: 'script.js'
}
},
babel: {
dist: {
options: {
sourceMap: true,
inputSourceMap: grunt.file.readJSON('script.js.map')
},
src: [
'script.js',
],
dest: 'app.js'
}
}
Example project: https://github.com/pra85/Grunt-Concat-Babel-Example

Related

Does this part of Gruntfile combine multiple files to one?

I have a Grunt file with the following content:
module.exports = function(grunt) {
// require('load-grunt-tasks')(grunt);
/* global process */
// configures browsers to run test against
// any of [ 'PhantomJS', 'Chrome', 'Firefox', 'IE']
var TEST_BROWSERS = ((process.env.TEST_BROWSERS || '').replace(/^\s+|\s+$/, '') || 'PhantomJS').split(/\s*,\s*/g);
// project configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
config: {
app: 'app',
sources: 'lib',
tests: 'test'
},
release: {
options: {
tagName: 'v<%= version %>',
commitMessage: 'chore(project): release v<%= version %>',
tagMessage: 'chore(project): tag v<%= version %>'
}
},
browserify: {
options: {
browserifyOptions: {
builtins: false
},
bundleOptions: {
detectGlobals: false,
insertGlobalVars: [],
debug: true
}
},
watch: {
files: {
'<%= config.app %>/bpmn-viewer.js': [ '<%= config.app %>/bpmn.js', 'index.js' ]
},
options: {
watch: true
}
},
standaloneViewer: {
files: {
'<%= config.app %>/bpmn-viewer.js': [ '<%= config.app %>/bpmn.js', 'index.js' ]
},
options: {
alias: [
'jquery:jquery',
'lodash:lodash',
'index.js:bpmn-js-diffing',
'<%= config.app %>/bpmn.js:bpmn-js'
]
}
},
},
jsdoc: {
dist: {
src: [ '<%= config.sources %>/**/*.js' ],
options: {
destination: 'docs/api',
plugins: [ 'plugins/markdown' ]
}
}
}
});
// tasks
grunt.registerTask('test', [ 'karma:single' ]);
grunt.registerTask('auto-test', [ 'karma:unit' ]);
// grunt.registerTask('default', [ 'jshint', 'test', 'browserify:standaloneViewer', 'jsdoc' ]);
grunt.registerTask('default', [ ]);
};
I know that somewhere in this file there must be an expression that minifies the code (I inherited the code from someone else, therefore I don't know how it works). The resulting file is called bpmn-viewer.js.
Could the lines
standaloneViewer: {
files: {
'<%= config.app %>/bpmn-viewer.js': [ '<%= config.app %>/bpmn.js', 'index.js' ]
},
mean that the files '<%= config.app %>/bpmn.js', 'index.js' should be combinded to <%= config.app %>/bpmn-viewer.js?
If possible, please provide links to the documentation that describes it.
There is some information missing, like the project you forked off and the package.json dependencies.
Luckily, I found https://github.com/bpmn-io/bpmn-js-diffing and that's probably the project you forked. Lets note that this project is very old and so are its dependencies, which I had to fix for it to work, so the versioning alone might change my results from yours.
What I didn't find were minified contents. The file app/bpmn-viewer.js is the concatenation result. The multiple files are concat into this one, yes, but there's only the browserify header that is always minified within bpmn-viewer.js.
First off, you commented load-grunt-tasks and the "default" grunt task, so I'm not sure you really ran grunt of this Gruntfile.js. Commenting it out cannot work, because there are no calls to grunt.loadNpmTasks as far as I'm aware, grunt plugins are not loaded without any loading instruction.
Now to the documentation. You are right that the concatenation happens because of the files field. This is part of Grunts Task definition layout.
Browserify analyzes the given files and concats them into one. That's the abstract description, more of that in the browserify handbook.
Still keep in mind: The versions of your forked project are very old.
So here's what I could find out in short:
No, the contents are not minified
A browserify header (which are minified) and the source map contents are added to the final file
If you really have minified content, please provide the package.json dependencies and the real running Gruntfile.js.

How to pass dynamic config to Gruntfile.js

I have written the grunt task to transpile ES6 to ES5. Following is my Gruntfile.js file
module.exports = function (grunt)
{
require("load-grunt-tasks")(grunt);
grunt.initConfig({
"babel": {
options: {
presets: ['es2015']
},
dist: {
files: [{
expand: true,
cwd: '/Users/pankajmeshram/Documents/IVWorkSpace/enfresh/resources/modules',
src: ['**/*.es6'],
dest: '/Users/pankajmeshram/Documents/IVWorkSpace/enfresh/resources/modules',
ext: '.js'
}]
}
}
});
grunt.registerTask("default", ["babel"]);
};
In this file, I want to pass the cwd and dest option dynamically so that I can use this for the different project as well as we have common build for all our projects.
If anyone work on this before, you can suggest some ways or any alternative solution for this task.
module.exports = function(grunt) {
require("load-grunt-tasks")(grunt);
grunt.initConfig({
"babel": {
options: {
presets: ['es2015']
},
dist: {
files: [{
expand: true,
cwd: "<%= cwd %>",
src: ['**/*.es6'],
dest: "<%= dest %>",
ext: '.js'
}]
}
}
});
grunt.registerTask("dynamicConfigs", "Set Dynamic Configs", function (argName, argValue) {
grunt.config.set(argName, argValue);
});
grunt.registerTask("default", ["dynamicConfigs:cwd:/Users/vineethgn/Documents/IVWorkSpace/enfresh/resources/modules", "dynamicConfigs:dest:/Users/vineethgn/Documents/IVWorkSpace/enfresh/resources/modules", "babel"]);
};
You can define those properties as template and then before calling babel task, call the newly created dynamicConfigs task.
Inside dynamicConfigs you are basically setting the key-value pair in grunt.config.
Make sure to call dynamicConfigs task with the parameters you want to set like in the sample code above.

grunt sass: compile only changed files

I have the following folder structure:
+ web
+ component
- component.js
- component.scss
- component.css
+ another
- another.js
- another.scss
- another.css
As you can see I compile every css into his component folder.
This is my configuration:
grunt.initConfig({
sass: {
dist: {
files: [{
expand: true,
cwd: './',
src: ['web/**/*.scss'],
dest: './',
ext: '.css'
}]
}
},
watch: {
files: ["web/**/*.scss"],
tasks: ['sass'],
options : { spawn: false }
}
});
Everything works fine, but the problem is that every time a scss file is changed, it compiles ALL the scss in my web folder.
I want to compile only the changed scss.
I also tried installing grunt-newer and changing the watch configuration in:
watch: {
files: ["web/**/*.scss"],
tasks: ['newer:sass'],
options : { spawn: false }
}
But it doesn't compile anything now.
ps: I would like to avoid mapping every single file in the sass configuration (scss -> css) since the rule is the same for all the files (same name, same folder), and because I have tons of them.
ok, i was close.. i'll post the answer as well, it may help someone.
i had to remove options : { spawn: false }, so my config file now is like this:
grunt.initConfig({
sass: {
dist: {
files: [{
expand: true,
cwd: './',
src: ['web/**/*.scss'],
dest: './',
ext: '.css'
}]
}
},
watch: {
files: ["web/**/*.scss"],
tasks: ['newer:sass']
}
});

Grunt / Babel error: Unable to write "dist" file (Error code: EISDIR)

I am new to Grunt and all its plugins, but I want to learn and setup some awesome front-end tools. With that said, I have been following the Grunt docs and some's similar issue with Grunt and Babel via Github, but I seem to keep getting the following traceback:
Running "babel:dist" (babel) task
Warning: Unable to write "dist" file (Error code: EISDIR). Use --force to continue.
Aborted due to warnings.
Any clearer explanation to this newbie would be HIGHLY appreciated. I'm new to programming in JS and setting up DevOps, so some helpful tips and best practices are encouraged.
Setup:
js_practice/ (Root Project)
|----package.json
All the distributions and packages
|---node_modules/
Server-Side (Node) support
|---es6/
| ------ test.js
|---dist/
Client (browser) support
|----public/
|---es6/ (this is within the public folder)
| ----- test2.js
|---dist/ (this is within the public folder)
Here is my current code:
Grunt file.js
module.exports = function(grunt) {
// All of your Grunt code must be specified inside this function!
// Setup configuration...
// Load tasks...
// Define tasks...
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
babel: {
options: {
sourceMap: true,
presets: ['babel-preset-es2015']
},
dist: {
files: [
// Node source
{
src: ['es6/**/*.js'],
dest: 'dist'},
// Browser source
{
src: ['public/es6/**/*.js'],
dest: 'public/dist'},
],
},
},
browserify: {
dist: {
options: {
transform: [["babelify", { "stage": 0 }]]
},
files: {
"build/bundle.js": "src/main.js"
}
}
},
jshint: {
scripts: {
src: ['scripts/**.js', 'lib/**.js']
},
tests: { // We can have more than one jshint task, this ones called `jshint:tests`
src: 'tests/**.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
},
scripts: {
expand: true,
cwd: 'scripts/',
src: '**.js',
dest: 'build/',
ext: '.min.js'
}
},
watch: {
scripts: {
files: ['**/*.js'],
tasks: ['jshint'],
},
styles: {
files: 'styles/**.less',
task: 'less:styles'
}
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-babel');
grunt.registerTask('default', ['babel','browserify','jshint']);
grunt.registerTask('build', ['jshint', 'uglify']);
};
Just expanding on what I said in the comments
Any clearer explanation to this newbie would be HIGHLY appreciated.
Nodejs is trying to write a file called dist, but produces an error because a directory with this name exists.
The cause of this is found in the babel task.
files: [{
src: ['es6/**/*.js'],
dest: 'dist'
},
// Browser source
{
src: ['public/es6/**/*.js'],
dest: 'public/dist'
}]
You have to tell Babel to take each file in es6/, transform them and place the new files in the dist/ folder. As it stand now, the transformer tries to create a file called dist. Rewriting it to
files: [{
expand: true,
cwd: 'es6/'
src: ['**/*.js'],
dest: 'dist/'
},
// Browser source
{
expand: true,
cwd: 'public/es6/'
src: ['**/*.js'],
dest: 'public/dist/'
}]
should yield a better result, but play around with it. Like I mentioned, I haven't used Grunt in a while. Take a look at the documentation on building the files object
And like I said in the comments, use jshint or other such tools (eslint is all the hype...) to keep your own code neat. Don't waste time by running a jshint task on lib files that you probably don't want to fix yourself anyway. And always run jshint on the source files, not files that are transformed by babel or browserify. It's just a tool to help you write better code, not some generator.

How to pass file name/options to Grunt minifyify

I'm using the minifyify plugin as recommended by this answer but I can't seem to find any way to pass flags/options to it when used with Grunt.
Here is the relevant part of my Gruntfile:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
options: {
browserifyOptions: {
debug: true
},
exclude: [/*...all vendor packages...*/],
transform: [
'brfs',
'debowerify',
'deamdify'
]
},
app: {
files: [{
expand: true,
cwd: 'web/resources/js',
src: '**/*.js',
dest: 'web/assets/js',
ext: '.min.js',
extDot: 'last'
}],
options: {
plugin: ['minifyify']
}
}
}
});
The compiled files are appended to with //# sourceMappingURL=bundle.map, which is incorrect. Also, the map files aren't being written to disk or generated at all.
How can I pass options in so that the sourceMappingURL is the same as the file name? So for example:
/web/assets/js/foo.min.js -> /web/assets/js/foo.js.map
/web/assets/js/bar.min.js -> /web/assets/js/bar.js.map
and so on...
you can pass options into grunt-browserify plugins/transforms if you pass in the transform as an array with the name as first item, and the options-object as the second:
plugin: [['minifyify', {your: 'options'}]]
for the transform option it is documented here: https://github.com/jmreidy/grunt-browserify#transform
for the plugin-option there is no documentation, but they generally work the same (see lib/runner.js, ans search for options.plugin)

Categories