我使用babel时是否需要js?

时间:2015-07-23 16:58:57

标签: javascript ecmascript-6

我正在尝试ES6,我使用gulp构建和babel转换为ES5。输出不在节点中运行,只是从带有标记的.htm文件链接。我想我需要添加

<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())

var _shapes = require('shapes');

3 个答案:

答案 0 :(得分:121)

  

使用babel时是否需要js?

您可能需要一些模块加载器,但它不是必需的RequireJS。你有几个选择。以下内容将帮助您入门。

rollup.js rollup-plugin-babel

Rollup是下一代JavaScript模块捆绑器。它本身可以理解ES2015模块,并且将生成一个不需要任何模块加载器即可运行的软件包。未使用的出口将从输出中削减,称为树木震动。

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

  1. 使用babel编译ES6代码,使用您选择的模块格式
  2. 将已编译的模块与模块加载器连接在一起,或者使用将为您遍历依赖项的捆绑器。
  3. 使用rollupjs,事情并没有真正起作用。汇总是第一步,而不是巴贝尔。它默认只能理解ES6模块。您必须提供一个入口模块,其中将遍历和连接依赖项。由于ES6允许模块中有多个命名导出,因此rollupjs足够智能去除未使用的导出,从而缩小了bundle的大小。不幸的是,rollupjs-s解析器不理解&gt; ES6语法,因此必须在汇总解析它们之前编译ES7模块,但编译不应该影响ES6导入。它是通过rollup-plugin-babel插件使用babel-preset-es2015-rollup预设来完成的(此预设与es2015相同,但模块转换器和外部助手插件除外)。因此,如果正确设置,汇总将对您的模块执行以下操作:

    1. 从文件系统中读取您的ES6-7模块
    2. babel插件将其编译为内存中的ES6
    3. 汇总解析ES6代码以进行导入和导出(使用橡子解析器,编译成汇总)
    4. 它遍历整个图形,并创建一个单独的包(它仍然可能具有外部依赖关系,并且可以以您选择的格式导出条目的导出)
    5. 示例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

      构建grunt示例
      // 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-rollup

      构建示例gulp
      // 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 + Browserify

      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的.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 + WebPack

      使用babel编译所有代码。我建议你使用amd模块变换器(在babel 6中称为babel-plugin-transform-es2015-modules-amd)。之后,将编译后的源与WebPack捆绑在一起。

      WebPack 2已经发布!它了解原生ES6模块,and will perform (or rather simulate) tree shaking使用babili - 内置死代码消除。现在(2016年9月)我仍然建议使用汇总和babel,虽然我的意见可能会随着WebPack 2的第一版发布而改变。欢迎在评论中讨论你的观点。

      自定义编译管道

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

      首先,您必须配置babel才能使用amd模块。默认情况下,babel会转换为CommonJS模块,这在浏览器中处理起来有点复杂,尽管browserify设法以一种很好的方式处理它们。

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

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

      检查生成的模块名称的转换代码,定义和必需模块之间通常不匹配。请参阅sourceRoot and moduleRoot

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

      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插件。

答案 1 :(得分:6)

准系统webpack 2

1)如果这是你的根目录:

的index.html

<html>
  ...
  <script src="./bundle.js"></script>
  ...
</html>

scripts.js中

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

shapes.js

export class Circle {
  ...
}

2)已安装节点node

3)在终端中运行以下命令:

$ npm install -g webpack

5)在根目录中运行以下命令:

$ webpack scripts.js bundle.js

您现在应该在根目录中有一个名为bundle.js的文件,该文件将是您的index.html将使用的文件。这是webpack的简约捆绑功能。您可以了解更多here

答案 2 :(得分:3)

浏览器中不存在

require,因此会出现此错误。你需要使用require.js或Browserify。