¿Necesito require js cuando uso babel?
Puede que necesite algún cargador de módulos, pero no es necesario RequireJS. Tienes varias opciones. Lo siguiente le ayudará a comenzar.
Rollup es un paquete de módulos JavaScript de próxima generación. Entiende los módulos ES2015 de forma nativa y producirá un paquete que no necesita ningún cargador de módulos para funcionar. Las exportaciones no utilizadas se recortarán de la salida, se llama agitación de árboles.
Ahora personalmente recomiendo usar rollupjs, ya que produce la salida más clara y es fácil de configurar, sin embargo, le da un aspecto diferente a la respuesta. Todos los demás enfoques hacen lo siguiente:
- Compile el código ES6 con babel, use el formato de módulo de su elección
- Concatenar los módulos compilados junto con un cargador de módulos O utilice un paquete que recorra las dependencias por usted.
Con rollupjs, las cosas realmente no funcionan de esta manera. Aquí, el rollup es el primer paso, en lugar de babel. Solo comprende los módulos ES6 por defecto. Debe proporcionar un módulo de entrada del cual se atravesarán y concatenarán las dependencias. Como ES6 permite múltiples exportaciones con nombre en un módulo, rollupjs es lo suficientemente inteligente como para eliminar las exportaciones no utilizadas, reduciendo así el tamaño del paquete. Desafortunadamente, el analizador rollupjs-s no comprende la sintaxis de ES6, por lo que los módulos de ES7 deben compilarse antes de que el rollup los analice, pero la compilación no debería afectar las importaciones de ES6. Se hace usando el rollup-plugin-babel
complemento con el babel-preset-es2015-rollup
preset (este preset es el mismo que el es2015, excepto el módulo transformer y el plugin external-helpers). Así que el rollup hará lo siguiente con sus módulos si está configurado correctamente:
- Lee su módulo ES6-7 del sistema de archivos
- El complemento de babel lo compila en ES6 en la memoria
- rollup analiza el código ES6 para importaciones y exportaciones (usando el analizador acorn, compilado en rollup)
- atraviesa todo el gráfico y crea un solo paquete (que aún puede tener dependencias externas, y las exportaciones de la entrada pueden exportarse, en un formato de su elección)
Ejemplo de compilación de nodejs:
// setup by `npm i rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`
// build.js:
require("rollup").rollup({
entry: "./src/main.js",
plugins: [
require("rollup-plugin-babel")({
"presets": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"]
})
]
}).then(bundle => {
var result = bundle.generate({
// output format - 'amd', 'cjs', 'es6', 'iife', 'umd'
format: 'iife'
});
require("fs").writeFileSync("./dist/bundle.js", result.code);
// sourceMaps are supported too!
}).then(null, err => console.error(err));
// setup by `npm i grunt grunt-rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`
// gruntfile.js
module.exports = function(grunt) {
grunt.loadNpmTasks("grunt-rollup");
grunt.initConfig({
"rollup": {
"options": {
"format": "iife",
"plugins": [
require("rollup-plugin-babel")({
"presets": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"]
})
]
},
"dist": {
"files": {
"./dist/bundle.js": ["./src/main.js"]
}
}
}
});
}
Ejemplo de compilación de gulp con gulp-rollup
// setup by `npm i gulp gulp-rollup rollup-plugin-babel babel-preset-es2015 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": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"]
})
],
entry: './src/main.js'
}))
.pipe(gulp.dest('./dist'));
});
Babel tiene un paquete ordenado llamado babelify . Su uso es simple y directo:
$ npm install --save-dev babelify babel-preset-es2015 babel-preset-react
$ npm install -g browserify
$ browserify src/script.js -o bundle.js \
-t [ babelify --presets [ es2015 react ] ]
o puede usarlo desde node.js:
$ npm install --save-dev browserify babelify babel-preset-es2015 babel-preset-react
...
var fs = require("fs");
var browserify = require("browserify");
browserify(["./src/script.js"])
.transform("babelify", {presets: ["es2015", "react"]})
.bundle()
.pipe(fs.createWriteStream("bundle.js"));
Esto transpilará y concatenará su código a la vez. Browserify's .bundle
incluirá un pequeño cargador CommonJS y organizará sus módulos transpilados en funciones. Incluso puede tener importaciones relativas.
Ejemplo:
// project structure
.
+-- src/
| +-- library/
| | \-- ModuleA.js
| +-- config.js
| \-- script.js
+-- dist/
\-- build.js
...
// build.js
var fs = require("fs");
var browserify = require("browserify");
browserify(["./src/script.js"])
.transform("babelify", {presets: ["es2015", "react"]})
.bundle()
.pipe(fs.createWriteStream("dist/bundle.js"));
// config.js
export default "Some config";
// ModuleA.js
import config from '../config';
export default "Some nice export: " + config;
// script.js
import ModuleA from './library/ModuleA';
console.log(ModuleA);
Para compilar, simplemente ejecute node build.js
en la raíz de su proyecto.
Compila todo tu código usando babel. Te recomiendo que uses el transformador de módulo amd (llamado babel-plugin-transform-es2015-modules-amd
en babel 6). Después de eso, combine sus fuentes compiladas con WebPack.
¡WebPack 2 ya está disponible! Entiende los módulos nativos de ES6 y realizará (o más bien simulará) la agitación de árboles utilizando la eliminación de código muerto incorporada de babili -s. Por ahora (septiembre de 2016), todavía sugeriría usar rollup con babel, aunque mi opinión podría cambiar con la primera versión de WebPack 2. No dude en comentar sus opiniones en los comentarios.
Canalización de compilación personalizada
A veces, desea tener más control sobre el proceso de compilación. Puede implementar su propia canalización de esta manera:
Primero, debe configurar babel para usar módulos amd. De forma predeterminada, babel se transpila a módulos CommonJS, lo cual es un poco complicado de manejar en el navegador, aunque browserify se las arregla para manejarlos de una manera agradable.
- Babel 5:
{ modules: 'amdStrict', ... }
opción de uso
- Babel 6: usa el
es2015-modules-amd
complemento
No olvide activar la moduleIds: true
opción.
Compruebe el código transpilado para ver los nombres de los módulos generados, a menudo hay discrepancias entre los módulos definidos y requeridos. Consulte sourceRoot y moduleRoot .
Finalmente, debe tener algún tipo de cargador de módulos, pero no es necesario requirejs. Hay almondjs , una pequeña calza que funciona bien. Incluso puedes implementar el tuyo propio:
var __modules = new Map();
function define(name, deps, factory) {
__modules.set(name, { n: name, d: deps, e: null, f: factory });
}
function require(name) {
const module = __modules.get(name);
if (!module.e) {
module.e = {};
module.f.apply(null, module.d.map(req));
}
return module.e;
function req(name) {
return name === 'exports' ? module.e : require(name);
}
}
Al final, puede concatenar el calce del cargador y los módulos compilados juntos, y ejecutar un uglify en eso.
El código repetitivo de Babel está duplicado en cada módulo
De forma predeterminada, la mayoría de los métodos anteriores compilan cada módulo con babel individualmente y luego los concatenan juntos. Eso es lo que hace también babelify. Pero si observa el código compilado, verá que babel inserta una gran cantidad de texto estándar al principio de cada archivo, la mayoría de ellos están duplicados en todos los archivos.
Para evitar esto, puede utilizar el babel-plugin-transform-runtime
complemento.
require
que no existe en el navegador, debe utilizar alguna herramienta de compilación como Require.js, Browserify o Webpack.