javascript 如何在网页中使用 ECMAScript6 模块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28761120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:31:02  来源:igfitidea点击:

How to use ECMAScript6 modules within webpages

javascriptecmascript-6babeljs

提问by wmock

I'm pretty excited about using ECMAScript 6 features now via Babeljs - in particular, I'd love to start making my JavaScript code more modular using the new modules feature.

现在通过 Babeljs 使用 ECMAScript 6 特性让我非常兴奋——特别是,我很想开始使用新的模块特性使我的 JavaScript 代码更加模块化。

Here's what I've written so far:

这是我到目前为止所写的内容:

// ECMAScript 6 code - lib.js
export const sqrt = Math.sqrt;
export function square (x) {
  return x * x;
}

export function diag (x, y) {
  return sqrt(square(x) + square(y));
}

// ECMAScript 6 code - main.js
import { square, diag } from 'lib';
console.log(square(11));
console.log(diag(4, 3));

I understand that I can transpile this code from ES6 to ES5 via babel on the command line:

我知道我可以通过命令行上的 babel 将此代码从 ES6 转换为 ES5:

babel lib.js > lib6to5.js
babel main.js > main6to5.js

But what do I need to do to use this code within my HTML?

但是我需要做什么才能在我的 HTML 中使用这个代码?

For example, what would this index.html file look like:

例如,这个 index.html 文件会是什么样子:

<!-- index.html -->
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ECMAScript 6</title>

    <!-- What goes here? 
     How do I include main6to5.js and lib6to5.js to make this work in the browser? -->
    <script src="?????"></script>

  </head>
  <body>

  </body>
</html>

Thank you

谢谢

采纳答案by trekforever

Without using Modules:If you are not using modules (imports/exports), then you can simply transpile your code into ES5 and include those ES5 files in your html. Example:

不使用模块:如果您不使用模块(导入/导出),那么您可以简单地将代码转换为 ES5,并将这些 ES5 文件包含在您的 html 中。例子:

// ES6 - index.js
// arrow function
var result = [1, 2, 3].map(n => n * 2);
console.log(result);

// enhanced object literal
var project = "helloWorld";
var obj = {
    // Shorthand for ‘project: project'
    project,
    // Methods
    printProject() {
     console.log(this.project);
    },
    [ "prop_" + (() => 42)() ]: 42
};
console.log(obj.printProject());
console.log(obj);

Transpile to es5: babel index.js > es5.js

转译到es5: babel index.js > es5.js

In index.html, include <script src="es5.js"></script>Will print out the following in console:

index.html, include<script src="es5.js"></script>将在控制台中打印出以下内容:

[2,4,6]
helloWorld
{"project":"helloWorld","prop_42":42}

Using Modules:Now if you are using modules (which is your case with lib.jsand main.js), after converting your code into ES5 you also have to bundle them (from AMD/CommonJS/Modules to code that your browser can understand). You can do this with various build systems like gulp, webpack, browserify, etc. I'm going to use browserify as an example here.

使用模块:现在,如果您正在使用模块(这就是您使用lib.js和的情况main.js),在将您的代码转换为 ES5 之后,您还必须捆绑它们(从 AMD/CommonJS/Modules 到您的浏览器可以理解的代码)。你可以用不同的生成系统,如这样做一饮而尽的WebPackbrowserify,等我将使用browserify在这里举例。

Say my folder structure looks like this:

假设我的文件夹结构如下所示:

es6
|- src
  |- lib.js
  |- main.js
|- compiled
|- index.html

I run babel to transpile my files /srcto /compiledfolder: babel src --out-dir compiled.

我运行 babel 将我的文件转换/src/compiled文件夹:babel src --out-dir compiled.

Now I have my ES5 code in the compiled folder. I install browserify in the cmd line and then bundle my main.js (entry point) in my compiled folder

现在我在编译文件夹中有我的 ES5 代码。我在 cmd 行中安装 browserify,然后将我的 main.js(入口点)捆绑在我编译的文件夹中

~/es6 ? npm install --global browserify
~/es6 ? browserify ./compiled/main.js -o ./bundle.js

Now I have bundle.jswhich is look like this:

现在我有bundle.js它看起来像这样:

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";

exports.square = square;
exports.diag = diag;
var sqrt = exports.sqrt = Math.sqrt;

function square(x) {
    return x * x;
}

function diag(x, y) {
    return sqrt(square(x) + square(y));
}

Object.defineProperty(exports, "__esModule", {
    value: true
});
},{}],2:[function(require,module,exports){
"use strict";

var _lib = require("./lib");

var square = _lib.square;
var diag = _lib.diag;

console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
},{"./lib":1}]},{},[2]);

Then in your index.html:

然后在你的 index.html 中:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ECMAScript 6</title>

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

  </head>
  <body>

  </body>
</html>

Then simply open up your index.html, and your console should give you the following:

然后只需打开您的index.html,您的控制台就会为您提供以下信息:

 121           bundle.js:27
 5             bundle.js:28

回答by Andrew Odri

I started out by trying the same thing, but eventually found that Gulp really helped out a lot.

我开始尝试同样的事情,但最终发现 Gulp 真的帮了大忙。

One thing to keep in mind: babel source.js > destination.jswon't polyfill new ES6 syntax. Your code right now isn't using any letstatements, destructured assignment, generator functions, or anything like that; but if you do add that at a later stage, you will need a more sophisticated transformation.

要记住的一件事:babel source.js > destination.js不会对新的 ES6 语法进行 polyfill。你的代码现在没有使用任何let语句、解构赋值、生成器函数或类似的东西;但如果您在稍后阶段添加它,您将需要更复杂的转换。

Here is an answer that explains how to setup the gulp file: Javascript 6to5 (now Babel) export module usage(Disclaimer: It is one of my answers :P)

这是一个解释如何设置gulp文件的答案:Javascript 6to5(现在是 Babel)导出模块使用(免责声明:这是我的答案之一:P)

Here are the steps specific to your case:

以下是针对您的案例的具体步骤:

  1. Create a file called gulpfile.jsin your directory with the following in it:
  1. 创建一个gulpfile.js在您的目录中调用的文件,其中包含以下内容:
var gulp = require('gulp');
var browserify = require('browserify');
var babelify= require('babelify');
var util = require('gulp-util');
var buffer = require('vinyl-buffer');
var source = require('vinyl-source-stream');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');

gulp.task('build', function() {
  browserify(['./lib.js', './main.js'], { debug: true })
  .add(require.resolve('babel/polyfill'))
  .transform(babelify)
  .bundle()
  .on('error', util.log.bind(util, 'Browserify Error'))
  .pipe(source('app.js'))
  .pipe(buffer())
  .pipe(sourcemaps.init({loadMaps: true}))
  .pipe(uglify({ mangle: false }))
  .pipe(sourcemaps.write('./'))
  .pipe(gulp.dest('./'));
});

gulp.task('default', ['build']);
  1. Run npm install gulp browserify babel babelify gulp-util vinyl-buffer vinyl-source-stream gulp-uglify gulp-sourcemapsto install the needed dependencies.
  2. Run gulpto bundle everything together.
  3. Use the bundled script in your HTML with this element: <script src="app.js"></script>
  1. 运行npm install gulp browserify babel babelify gulp-util vinyl-buffer vinyl-source-stream gulp-uglify gulp-sourcemaps以安装所需的依赖项。
  2. 运行gulp将所有东西捆绑在一起。
  3. 将 HTML 中的捆绑脚本与此元素一起使用: <script src="app.js"></script>

The nice thing in addition to polyfills being added is that the code is minified, and you get sourcemaps, which means even in your developer tools, you can debug the ES6 code itself.

除了添加 polyfill 之外,还有一个好处是代码被缩小了,并且您可以获得源映射,这意味着即使在您的开发人员工具中,您也可以调试 ES6 代码本身。



Note:While the import statement you are using is correct according to the ES6 draft specification, Babel won't like it. You will need to add a ./, so that it looks something like this:

注意:虽然根据 ES6 草案规范,您使用的 import 语句是正确的,但 Babel 不会喜欢它。您将需要添加一个./,使其看起来像这样:

import { square, diag } from './lib';

I suspect this is because the transformation happens in Node.js, and this differentiates a file from a node module. As a side point, you can write ES6 for node do requires with import statements :)

我怀疑这是因为转换发生在 Node.js 中,这将文件与节点模块区分开来。顺便说一句,您可以使用 import 语句为 node do requires 编写 ES6 :)

回答by AardVark71

[Note: I realise my answer is poor as it doesn't fully reflect the questioners intention to use ES6 modules via babeljs in a front-end workflow. Keeping the answer her for those that want to use ES6 modules within a webpage]

[注意:我意识到我的回答很糟糕,因为它没有完全反映提问者在前端工作流程中通过 babeljs 使用 ES6 模块的意图。为那些想要在网页中使用 ES6 模块的人保留答案]

Try using jspm.iofor loading the ES6 modules in the browser without transpiling upfront with babel. A plunker can be found here

尝试使用jspm.io在浏览器中加载 ES6 模块,而无需预先使用 babel 进行转换。一个plunker可以在这里找到

jspm works on top on of system.jswhich tries to be a loader for any module format (ES6, AMD, CommonJS)..

JSPM作品上的顶部system.js它试图对任何模块格式(ES6,AMD,CommonJS的)加载器..

To make this work in my browser, I based myself on this jspm ES6 demo. Just copied System.jsand es6-module-loader.jsin a js/lib folder and copied your es6 js files in the js folder. Then the html just looks like this:

为了在我的浏览器中完成这项工作,我基于这个 jspm ES6 演示。刚刚将System.jses6-module-loader.js复制到 js/lib 文件夹中,并将您的 es6 js 文件复制到 js 文件夹中。然后html看起来像这样:

<html>
    <body>
        Test .. just open up the Chrome Devtools console to see the ES6 modules output using jspm
        <script src="js/lib/system.js"></script>
        <script>System.import("main");</script> </body>
</html>

A plunker can be found here

一个plunker可以在这里找到

回答by user5321531

Would one of the --modulesswitches compile into JS that can be directly included in a web page in the same way that the --scriptflag will compile to browser JS (--scriptcan not be used with modules)? See https://github.com/google/traceur-compiler/wiki/Options-for-Compiling

其中一个--modules开关是否会编译成可以直接包含在网页中的 JS,就像该--script标志将编译为浏览器 JS(--script不能与模块一起使用)一样?请参阅https://github.com/google/traceur-compiler/wiki/Options-for-Compiling