Ho bisogno di require js quando uso babel?
Potrebbe essere necessario un caricatore di moduli, ma non è necessario RequireJS. Hai diverse opzioni. Quanto segue ti aiuterà a iniziare.
Rollup è un bundler di moduli JavaScript di nuova generazione. Comprende i moduli ES2015 in modo nativo e produrrà un bundle che non necessita di alcun caricatore di moduli per funzionare. Le esportazioni inutilizzate verranno tagliate dall'output, si chiama scuotimento degli alberi.
Ora personalmente consiglio di utilizzare rollupjs, poiché produce l'output più chiaro ed è facile da configurare, tuttavia fornisce un aspetto diverso alla risposta. Tutti gli altri approcci fanno quanto segue:
- Compila il codice ES6 con babel, usa il formato del modulo che preferisci
- Concatena i moduli compilati insieme a un caricatore di moduli O usa un bundler che attraverserà le dipendenze per te.
Con rollupjs le cose non funzionano davvero in questo modo. Qui, il rollup è il primo passo, invece di Babel. Capisce solo i moduli ES6 per impostazione predefinita. È necessario fornire un modulo di ingresso di cui verranno attraversate e concatenate le dipendenze. Poiché ES6 consente più esportazioni con nome in un modulo, rollupjs è abbastanza intelligente da eliminare le esportazioni inutilizzate, riducendo così le dimensioni del pacchetto. Sfortunatamente il parser di rollupjs-s non comprende la sintassi> ES6, quindi i moduli ES7 devono essere compilati prima che il rollup li analizzi, ma la compilazione non dovrebbe influenzare le importazioni di ES6. Si fa utilizzando il rollup-plugin-babelplugin con il babel-preset-es2015-rolluppreset (questo preset è lo stesso di quello es2015, tranne il trasformatore del modulo e il plugin per aiutanti esterni). Quindi il rollup farà quanto segue con i tuoi moduli se impostato correttamente:
- Legge il tuo modulo ES6-7 dal filesystem
- Il plugin babel lo compila in ES6 in memoria
- rollup analizza il codice ES6 per importazioni ed esportazioni (utilizzando il parser di ghiande, compilato in rollup)
- attraversa l'intero grafico e crea un singolo bundle (che potrebbe ancora avere dipendenze esterne e le esportazioni della voce potrebbero essere esportate, in un formato a tua scelta)
Esempio di build 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"]
}
}
}
});
}
// 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 ha un bel pacchetto chiamato babelify . Il suo utilizzo è semplice e diretto:
$ 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 ] ]
oppure puoi usarlo da 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"));
Questo transpile e concatenerà il tuo codice in una volta. Browserify .bundleincluderà un simpatico caricatore CommonJS e organizzerà i tuoi moduli trasferiti in funzioni. Puoi anche avere importazioni relative.
Esempio:
// 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);
Per compilare basta eseguire node build.jsnella root del progetto.
Compila tutto il tuo codice usando babel. Ti consiglio di utilizzare il trasformatore del modulo amd (chiamato babel-plugin-transform-es2015-modules-amdin babel 6). Dopo di che raggruppa i tuoi sorgenti compilati con WebPack.
WebPack 2 è disponibile! Comprende i moduli ES6 nativi ed eseguirà (o meglio simulerà) lo shaking dell'albero usando l' eliminazione del codice morto incorporata babili -s. Per ora (settembre 2016) suggerirei ancora di utilizzare il rollup con babel, anche se la mia opinione potrebbe cambiare con la prima versione di WebPack 2. Sentiti libero di discutere le tue opinioni nei commenti.
Pipeline di compilazione personalizzata
A volte vuoi avere un maggiore controllo sul processo di compilazione. Puoi implementare la tua pipeline in questo modo:
Per prima cosa, devi configurare babel per usare i moduli amd. Per impostazione predefinita, babel esegue il transpiles nei moduli CommonJS, che è un po 'complicato da gestire nel browser, sebbene browserify riesca a gestirli in modo carino.
- Babel 5: usa l'
{ modules: 'amdStrict', ... }opzione
- Babel 6: usa il
es2015-modules-amdplugin
Non dimenticare di attivare l' moduleIds: trueopzione.
Controllare il codice traspilato per i nomi dei moduli generati, ci sono spesso discrepanze tra i moduli definiti e quelli richiesti. Vedere sourceRoot e moduleRoot .
Infine, devi avere una sorta di caricatore di moduli, ma non è necessario requirejs. C'è almondjs , uno spessore minuscolo che funziona bene. Puoi persino implementare il tuo:
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);
}
}
Alla fine, puoi semplicemente concatenare lo shim del caricatore ei moduli compilati insieme, ed eseguire un uglify su quello.
Il codice boilerplate di Babel è duplicato in ogni modulo
Per impostazione predefinita, la maggior parte dei metodi precedenti compila ogni modulo con babel individualmente, e poi li concatena insieme. Questo è ciò che fa anche babelify. Ma se guardi il codice compilato, vedi che babel inserisce molti boilerplate all'inizio di ogni file, la maggior parte di essi sono duplicati in tutti i file.
Per evitare ciò è possibile utilizzare il babel-plugin-transform-runtimeplugin.
requirenon esiste nel browser, è necessario utilizzare alcuni strumenti di compilazione come Require.js, Browserify o Webpack.