Browserify and Babel gulp tasks - javascript

I want to use both Browserify and Babel with my JavaScript. For this I created a gulp task
gulp.task('babel', function() {
return gulp.src('_babel/*.js')
.pipe(browserify({ insertGlobals : true }))
.pipe(babel({ presets: ['es2015'] }))
.pipe(gulp.dest('_dev/js'));
});
Unfortunately, when I want to use import within my code, I am getting an error:
ParseError: 'import' and 'export' may only appear at the top level
My main js file is very simple:
import 'directives/toggleClass';
I'm guessing that it is because of Babel (and it's use strict addition), but what can I do?

Babel maintains an official transform for Browserify called babelify and it should be used wherever possible if using babel and browserify.
Drop the use of babel directly and place babelify as a transform plugin for browserify. There are many ways to configure browserify but specifying config in your package.json would probably be easiest.
"browserify": {
"transform": [["babelify", { "presets": ["es2015"] }]]
}
Your gulp task will then be simplified
gulp.task('babel', function() {
return gulp.src('_babel/*.js')
.pipe(browserify({ insertGlobals : true }))
.pipe(gulp.dest('_dev/js'));
});
Browserify also exposes methods to do this programmatically so you will be able to configure the bundler from inside your gulp task (dropping the package config, although using the package is perfectly fine for this), check their documentation and experiment, I've done it before but its been a long time since I used gulp (using gulp here is just a complication you dont need, but I expect you are using it elsewhere in your build pipeline where it might be more helpful).

Related

How to apply babel plugin for certain dependency?

I have write a Babel plugin for transpiling some specific dependencies.
To reduce the compiling time of babel, I want to only use it for these dependencies, my babel.config.js is like
module.exports = {
plugins: [["plugin-a"], ["plugin-b"]]
// for `plugin-c` only apply to `./node_modules/certain_dependency`
I find only is a very useful config.
Is it possible to do that on Babel?

import for front end development

I would like to use the features of ES2016 for my front end development. Especially import and decorators are interesting for me.
I’ve started a small test project and created some different files with classes which I include with import. Babel generates the correct files but includes an require statement which does not work in a browser (as far as I know).
Are there any good tools to concat all files into a single javascript file ordered by their require? Or some libraries for gulp which do this for me?
You get the error because Babel translates your ES2016 code into CommonJS format, browser does not support it. You need some module bundler for creating bundle that can be used in browser:
Browserify
Webpack
Rollup
Example gulp build with gulp-rollup
// setup by `npm i gulp gulp-rollup rollup-plugin-babel babel-preset-es2016 babel-plugin-external-helpers --save-dev`
// gulpfile.js
var gulp = require('gulp'),
rollup = require('gulp-rollup');
gulp.task('bundle', function() {
gulp.src('./src/**/*.js')
// transform the files here.
.pipe(rollup({
// any option supported by Rollup can be set here.
"format": "iife",
"plugins": [
require("rollup-plugin-babel")({
"presets": [["es2016", { "modules": false }]],
"plugins": ["external-helpers"]
})
],
entry: './src/main.js'
}))
.pipe(gulp.dest('./dist'));
});

Typescript Modules Into Single JS file?

Ok, I am complete lost with this. I have just started using Typescript with Grunt JS and need some help.
I have a working Grunt file thats runs my TS and then a uglify process for site ready files, here is the config:
ts: {
default: {
files: {
'/js/builds/main.js': ['/typescript/main/build.ts'],
'/js/builds/public.js': ['/typescript/public/build.ts']
}
},
options: {
target: 'ES5',
fast: 'never',
sourceMap: false,
allowJs: true,
declaration: false,
module: 'amd'
},
},
'uglify': {
options: {
preserveComments: 'some',
},
my_target: {
files: {
'src/js/main.js': ['/js/builds/main.js'],
'src/js/public.js': ['/js/builds/public.js']
}
}
},
watch: {
'JS': {
files: [
'/js/**/*.js',
'/typescript/**/*.ts',
'/typescript/**/**/*.ts'
],
tasks: ['ts', 'uglify'],
options: {
spawn: false,
},
}
}
So now I am working on my Typescript files, but I having a lot of issues, I want to use Typescript as a module system but to output into a single file, right now its set to AMD, which needs Require JS of which I dont know.
Right now I don't have the time to learn Typescript and Require JS. So where is what I have got right now,
test.js:
export class testMe {
constructor() { }
LogingData() {
console.log( 'Data being logged...' );
}
}
Then in my build ts file,
import {testMe} from "./clients/clients";
However this needs Require JS or module loading system in order to get it to run? I have tried using commonJs but it seems support for that was removed in Typescript 1.8 (I am using 2.0).
So how do I get my Grunt / Typescript into a single standard ES5 complied code, while using modules for Typescript?
Many thanks
UPDATE
This question & answer, Typescript compile to single file does not give an answer for how to setup grunt to use Typescript into a single file! Plus the answer states that Typescript 1.8+ will fix that issue - But the version I am using does not.
I am using Grunt to compile the TS code into one standard javascript file, without the use of System or Require JS. So I can use that within my HTML code.
The end goal would be to have two single files. To explain I have lots of single .ts files for two sections, one main and the other public - I have not work on the public section, just the main one, so all my tests I been on that section.
So to layout my file/folder path:
js/
builds/
main.js < targer end file
public.js <- target end file
typescript
main/
settings/
classA.ts
somethingelse.ts
othersection/
something.ts
buildMain.ts <- *1
*1 This file then takes all the ts files, via imports (not sure if thats the correct way) and then builds the complete standard single .js file.
I hope that explains my query in more detail.
Thanks
UPDATE 2:
I would just like to add that I am getting a single file, e.g. main.js but that is not a standard Javascript complied file. I don't want to use Require JS or any other external module loading system.
I want to use external .ts files has modules import them into a 'build' file and have that file compile down to a standard self contained javascript file without the need to include require js or anything else.
Hope that clears it up a little more..
Thanks.
I believe you can use --outfile to get everything into one file. The trick is to remove import and export statements and use /// <reference path="path/to/file.ts" /> on the first lines to declare the dependency / ordering relationships. Since it is the import/export statements that produce the calls to CommonJS or Require, omitting them prevents their generation.
Ref: https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html
For two output files, you'll probably need two tsconfig.json. (I might be incorrect here.)
If you don't bother with .d.ts files you can simply use just --module=commonjs(it is and will be supported) to compile each file into .js and then browserify to concat all modules together.
I'm using CLI scripts instead of grunt but it should be obvious what it does:
$ ./node_modules/.bin/tsc --module commonjs main.ts
$ ./node_modules/.bin/browserify main.js -o bundle.js
Then you can run it like any other JavaScript from browser or CLI using node.
There's also --outFile option for tsc but this is limited only to amd and systemjs modules so I think it's easier to stick to commonjs and browserify.
browserify is an amazing tool. You can generate UMD module with --standalone parameter that works also as global or exclude any external dependencies.
I highly recommend you to read the Official Handbook: https://github.com/substack/browserify-handbook

Babelify the files in place, in multiple directories

How can I use babel to transpile the JavaScript files containing ES6 stuff, in different directories? I want the result to be in the same directories (e.g. having foo/bar/index.js, I want to get the ES5 code in the same file, by overriding it).
To override one directory I use:
babel lib/ -d lib
This works for one folder (overrides all the content in the lib directory).
How can I do the same for two or more directories? For example, how can I do that for lib/ and bin/?
AFAIK the babel CLI isn't complex enough to support this use-case in a single command. However you could concatenate two commands to achieve the same result:
babel lib/ -d lib && babel bin/ -d bin
Or you could write a script that does this for you, using gulp or another build tool of your choice. For example (untested):
gulp.task('default', () =>
gulp.src(['bin/**/*.js', 'lib/**/*.js'], { base: './' })
.pipe(babel())
.pipe(gulp.dest('.'))
)
The codemod CLI is perfect for this.
It will just modify your files in place:
codemod --plugin babel-transformer.js src/**/*.js

Running tasks configured across multiple grunt.js files

I have a node app that includes multiple unpublished modules. My app's package.json includes a few git dependencies:
"module-a": "git+ssh://git#github.com:me/module-a.git",
"module-b": "git+ssh://git#github.com:me/module-b.git"
and each of those have their own grunt config. Eg in node_modules/module-a/grunt.js:
module.exports = function(grunt) {
grunt.initConfig({
lint: {
files: ['server/**/*.js', 'test/**/*.js']
},
jshint: {
options: require('./lint-ci')
}
});
grunt.registerTask('default', 'lint');
};
(they also run tests, etc, but I'm keeping it simple here)
Is there a built-in way to do this with grunt? Note that I want to keep the dependent grunt.js files for convenience when I've only changed something within that dependency.
The only solutions I have found are
build up my main grunt.js programmatically (eg, iterating over my dependencies in package.json to build the lint and test config)
call grunt multiple times using --config node_modules/module-a/grunt.js
Neither seems ideal. Is there a better way?
Just a thought but have you looked at grunt-hub?
https://github.com/shama/grunt-hub

Categories