当我使用巴贝尔时,是否需要js? [英] Do I need require js when I use babel?

查看:110
本文介绍了当我使用巴贝尔时,是否需要js?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试用ES6,Im使用gulp建立和传播到ES5。输出没有在节点中运行,只是从具有标签的.htm文件链接到。我想我需要添加

Im experimenting with ES6, and Im using gulp to build and babel to transpile to ES5. The output is not being run in node, just linked to from a .htm file with a tag. Im thinking I need to add

<script src='require.js'></script>

或类似的东西。

尝试导入/导出。

////////////////scripts.js
import {Circle} from 'shapes';

c = new Circle(4);

console.log(c.area());


/////////////////shapes.js
export class Circle {

    circle(radius) {
        this.radius = radius;
    }

    area() {
        return this.radius * this.radius * Math.PI;
    } 

}

错误是

Uncaught ReferenceError: require is not defined

指的是(在gulp中的.pipe(babel())之后)

Refers to this (after .pipe(babel()) in gulp)

var _shapes = require('shapes');


推荐答案


js当我使用babel?


您可能需要一些模块加载程序,但不需要RequireJS。你有几个选择。以下内容将帮助您开始使用。

You might need some module loader, but it is not necessary RequireJS. You have several options. The following will help you to get started.

汇总是下一代JavaScript模块捆绑器。它本身了解ES2015模块,并将生成一个不需要任何模块加载器来运行的软件包。未使用的导出将从输出中修剪,称为树状。

Rollup is a next-generation JavaScript module bundler. It understands ES2015 modules natively, and will produce a bundle that doesn't need any module loader to operate. Unused exports will be trimmed from the output, it's called tree-shaking.

现在我个人建议使用rollupjs,因为它产生最清晰的输出,并且易于设置,然而,它给出了一个不同的方面的答案。所有其他方法都执行以下操作:

Now I personally recommend using rollupjs, as it produces the clearest output, and is easy to setup, however, it gives a different aspect to the answer. All the other approaches do the following:


  1. 使用babel编译ES6代码,使用您选择的模块格式

  2. 将编译后的模块与模块加载器连接起来,或者使用一个捆绑程序来覆盖您的依赖关系。

rollupjs的东西并没有真正的工作这样。在这里,汇总是第一步,而不是巴贝尔。默认情况下,它只能理解ES6模块。您必须给出一个条目模块,其中依赖关系将被遍历并连接。由于ES6允许在模块中使用多个命名导出,所以rollupjs足够聪明,可以去除未使用的导出,从而缩小了bundle的大小。不幸的是,rollupjs的解析器不能理解> ES6语法,所以ESS模块必须在汇总解析之前进行编译,但编译不应影响ES6导入。这是通过使用 rollup-plugin-babel 插件与 babel-preset-es2015-rollup 预设(这个预设与es2015相同,模块变压器和外辅助插件除外)。因此,如果正确设置,汇总将对您的模块执行以下操作:

With rollupjs things doesn't really work this way. Here, rollup is the first step, instead of babel. It only understands ES6 modules by default. You must give an entry module of which the dependencies will be traversed and concatenated. As ES6 allows multiple named exports in a module, rollupjs is smart enough to strip unused exports, thus shrinking bundle size. Unfortunately rollupjs-s parser doesn't understand >ES6 syntax, so ES7 modules have to be compiled before rollup parses them, but the compilation should not affect the ES6 imports. It is done by using the rollup-plugin-babel plugin with the babel-preset-es2015-rollup preset (this preset is the same as the es2015 one, except the module transformer and the external-helpers plugin). So rollup will do the following with your modules if correctly set up:


  1. 从文件系统中读取您的ES6-7模块

  2. babel插件将其编译为内存中的ES6

  3. 汇总解析导入和导出的ES6代码(使用橡胶解析器,编译成汇总)

  4. 它遍历整个图形,并创建一个单独的包(它仍然可能具有外部依赖关系,并且条目的导出可能以您选择的格式导出)

  1. Reads your ES6-7 module from the filesystem
  2. The babel plugin compiles it to ES6 in memory
  3. rollup parses the ES6 code for imports and exports (using acorn parser, compiled into rollup)
  4. it traverses the whole graph, and creates a single bundle (which still might have external dependencies, and the entry's exports might be exported, in a format of your choice)



示例nodejs build:



Example nodejs build:

// 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));



使用 grunt-rollup



Example grunt build with grunt-rollup

// 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"]
        }
      }
    }
  });
}



示例gulp构建与 gulp-rollup



Example gulp build with 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'));
});






Babelify + 浏览



Babel有一个整齐的包,叫做 babelify 。它的用法很简单直观:


Babelify + Browserify

Babel has a neat package called babelify. It's usage is simple and straightforward:

$ 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:

or you can use it from 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的 .bundle 将包含一个很好的小型CommonJS加载器,并将您的蜕化模块组织成功能。您可以使用相对导入。

This will transpile and concatenate your code at once. Browserify's .bundle will include a nice little CommonJS loader, and will organize your transpiled modules into functions. You can even have relative imports.

// 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 在您的项目根目录。

To compile just run node build.js in your project root.

编译所有你的代码使用babel。我建议您在babel 6中使用amd模块变压器(称为 babel-plugin-transform-es2015-modules-amd )。使用WebPack捆绑您的编译源。

Compile all your code using babel. I recommend you to use the amd module transformer (called babel-plugin-transform-es2015-modules-amd in babel 6). After that bundle your compiled sources with WebPack.

WebPack 2已经出来了!它了解本机ES6模块,并将使用 babili -s内置死码消除。现在(2016年9月),尽管我的意见可能会随着WebPack 2的第一个版本而改变,但仍然建议您使用汇总。请随时在评论中讨论您的意见。

WebPack 2 is out! It understands native ES6 modules, and will perform (or rather simulate) tree shaking using babili-s builtin dead code elimination. For now (September 2016) I would still suggest to use rollup with babel, although my opinion might change with the first release of WebPack 2. Feel free to discuss your opinions in the comments.

有时您希望对编译过程有更多的控制权。您可以这样实现自己的管道:

Sometimes you want to have more control over the compilation process. You can implement your own pipeline like this:

首先,您必须配置babel以使用amd模块。默认情况下,传播到CommonJS模块,这在浏览器中处理有点复杂,尽管browserify设法以很好的方式处理它们。

First, you have to configure babel to use amd modules. By default babel transpiles to CommonJS modules, which is a little complicated to handle in the browser, although browserify manages to handle them in a nice way.


    <宝贝5:使用 {modules:'amdStrict',...} 选项
  • Babel 6:使用 es2015-modules-amd 插件

  • Babel 5: use { modules: 'amdStrict', ... } option
  • Babel 6: use the es2015-modules-amd plugin

不要忘记打开 moduleIds:true 选项。

检查所生成的模块名称的折叠代码,定义模块和必需模块之间经常出现不匹配。请参阅 sourceRoot和moduleRoot

Check the transpiled code for generated modul names, there are often mismatches between defined and required modules. See sourceRoot and moduleRoot.

最后,你必须要有一些模块装载器,但这不是必需的。 almondjs 是一个很小的需要垫片,效果很好。你甚至可以实现自己的:

Finally, you have to have some kind of module loader, but it isn't necessairy requirejs. There is almondjs, a tiny require shim that works well. You can even implement your own:

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。

At the end, you can just concatenate the loader shim and the compiled modules together, and running an uglify on that.

默认情况下,大多数上述方法单独使用babel编译每个模块,然后将它们连接在一起。这也是babelify也是。但是,如果您查看编译的代码,您会看到babel在每个文件的开头插入大量样板,其中大部分都是在所有文件中重复的。

By default, most of the above methods compile each module with babel individually, and then concatenate them together. That's what babelify does too. But if you look at the compiled code, you see that babel inserts lots of boilerplate at the beginning of each file, most of them are duplicated across all files.

为了防止这可以使用 babel- plugin-transform-runtime 插件。

To prevent this you can use the babel-plugin-transform-runtime plugin.

这篇关于当我使用巴贝尔时,是否需要js?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆