Чи потрібно мені вимагати js, коли я використовую babel?
Вам може знадобитися якийсь завантажувач модулів, але це не обов'язково RequireJS. У вас є кілька варіантів. Наступне допоможе вам розпочати роботу.
Rollup - це пакет модулів JavaScript наступного покоління. Він чудово розуміє модулі ES2015 і створить пакет, для роботи якого не потрібен завантажувач модулів. Невикористаний експорт буде обрізаний з випуску, це називається похитуванням дерев.
Зараз я особисто рекомендую використовувати rollupjs, оскільки він дає найбільш чіткий результат і простий у налаштуванні, однак він надає інший аспект відповіді. Усі інші підходи роблять наступне:
- Складіть код ES6 за допомогою Babel, використовуйте формат модуля на ваш вибір
- Об’єднайте скомпільовані модулі разом із завантажувачем модулів АБО використовуйте пакет, який пройде залежності для вас.
З rollupjs все не так працює. Тут зведення - це перший крок, а не бабель. Він за замовчуванням розуміє лише модулі ES6. Ви повинні вказати модуль введення, залежності якого будуть обходити та об'єднувати. Оскільки ES6 дозволяє багаторазово експортувати імена в модулі, rollupjs досить розумний, щоб позбавити невикористаного експорту, тим самим зменшуючи розмір пакета. На жаль, аналізатор rollupjs-s не розуміє> синтаксис ES6, тому модулі ES7 повинні бути скомпільовані перед тим, як збірний аналізує їх, але компіляція не повинна впливати на імпорт ES6. Це робиться за допомогою rollup-plugin-babel
плагіна з babel-preset-es2015-rollup
пресетом (цей пресет є таким же, як і у es2015, за винятком модульного трансформатора та плагіна зовнішніх помічників). Тож зведене виконає з вашими модулями наступне, якщо правильно налаштовано:
- Зчитує ваш модуль ES6-7 із файлової системи
- Плагін babel компілює його до ES6 в пам’яті
- зведений аналізує код ES6 для імпорту та експорту (за допомогою аналізатора жолудів, зведеного в зведений)
- він обводить весь графік і створює єдиний пакет (який все ще може мати зовнішні залежності, а експортування запису може бути експортовано у форматі на ваш вибір)
Приклад побудови 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 має акуратний пакет під назвою babelify . Його використання просте і зрозуміле:
$ 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 ] ]
або ви можете використовувати його з 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"));
Це призведе до транпіляції та конкатенації вашого коду відразу. Browserify's.bundle
включатиме приємний маленький завантажувач CommonJS і організує ваші перекладені модулі у функції. Ви навіть можете мати відносний імпорт.
Приклад:
// 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);
Для компіляції просто запустіть node build.js
у корені проекту.
Скомпілюйте весь свій код, використовуючи babel. Я рекомендую вам скористатися трансформатором модуля amd (називається babel-plugin-transform-es2015-modules-amd
в Babel 6). Після цього об’єднайте свої скомпільовані джерела з WebPack.
WebPack 2 вийшов! Він розуміє власні модулі ES6 і виконуватиме (або, вірніше, імітуватиме) струшування дерев, використовуючи вбудований вбудований мертвий код babili . Наразі (вересень 2016 р.) Я все-таки пропоную використовувати зведення з babel, хоча моя думка може змінитися з першим випуском WebPack 2. Не соромтеся обговорювати свої думки в коментарях.
Спеціальний конвеєр компіляції
Іноді ви хочете мати більше контролю над процесом компіляції. Ви можете реалізувати свій власний конвеєр таким чином:
По-перше, вам потрібно налаштувати babel для використання модулів amd. За замовчуванням babel транспілює до модулів CommonJS, що трохи складно обробляти в браузері, хоча browserify вдається обробляти їх приємно.
- Бабель 5:
{ modules: 'amdStrict', ... }
варіант використання
- Babel 6: використовуйте
es2015-modules-amd
плагін
Не забудьте увімкнути moduleIds: true
опцію.
Перевірте перекладений код на наявність сформованих імен модулів, часто виникають невідповідності між визначеними та необхідними модулями. Див. SourceRoot та moduleRoot .
Нарешті, ви повинні мати якийсь модуль завантажувача, але це не обов’язково requirejs. Є мигдаль , крихітна прокладка, яка добре працює. Ви навіть можете реалізувати власні:
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);
}
}
Врешті-решт, ви можете просто об'єднати прошивку завантажувача та скомпільовані модулі разом, і запустити uglify на цьому.
Зразковий код Babel продублюється в кожному модулі
За замовчуванням більшість з вищезазначених методів компілюють кожен модуль за допомогою babel окремо, а потім об'єднують їх разом. Це те, що робить і babelify. Але якщо ви подивитеся на скомпільований код, то побачите, що babel вставляє багато шаблонів на початку кожного файлу, більшість з них дублюються у всіх файлах.
Щоб запобігти цьому, ви можете використовувати babel-plugin-transform-runtime
плагін.
require
в браузері не існує, вам потрібно використовувати якийсь інструмент побудови, такий як Require.js, Browserify або Webpack.