将现有的AMD模块导入ES6模块

时间:2015-09-27 06:32:48

标签: javascript module requirejs ecmascript-6 amd

我有一个现有的应用程序,我使用 RequireJS 定义了AMD模块。我使用" text"和" i18n"我的项目中广泛使用requirejs的插件。 我最近一直在试验ES6模块,并希望在我的应用程序中创建新模块时使用它们。但是,我想重用现有的AMD模块并在定义ES6模块时导入它们。

这甚至可能吗?我知道Traceur和Babel可以从ES6模块创建AMD模块,但这仅适用于不依赖于现有AMD模块的新模块,但我找不到重用现有AMD模块的示例。

任何帮助将不胜感激。这对我来说是一个阻止我开始使用所有ES6好东西。

由于

3 个答案:

答案 0 :(得分:4)

是的,可以做到。使用以下结构创建一个新应用程序:

gulpfile.js
index.html
js/foo.js
js/main.es6
node_modules

安装gulpgulp-babel。 (我更喜欢在本地安装gulp,但您可能需要全局:这取决于您。)

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Something</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.20/require.js"></script>
    <script>
    require.config({
        baseUrl: "js",
        deps: ["main"]
    });
    </script>
</head>
<body>
</body>
</html>

gulpfile.js

"use strict";

var gulp = require('gulp');
var babel = require('gulp-babel');

gulp.task("copy", function () {
    return gulp.src(["./js/**/*.js", "./index.html"], { base: '.' })
        .pipe(gulp.dest("build"));
});

gulp.task("compile-es6", function () {
    return gulp.src("js/**/*.es6")
        .pipe(babel({"modules": "amd"}))
        .pipe(gulp.dest("build/js"));
});

gulp.task("default", ["copy", "compile-es6"]);

js/foo.js

define(function () {
    return {
        "foo": "the value of the foo field on module foo."
    };
});

js/main.es6

import foo from "foo";

console.log("in main: ", foo.foo);

运行gulp构建应用程序后,在浏览器中打开文件build/index.html。你会在控制台上看到:

in main:  the value of the foo field on module foo.

ES6模块main能够加载AMD模块foo并使用导出的值。也可以让本机AMD模块加载已转换为AMD的ES6模块。一旦Babel完成其工作,就AMD装载器而言,它们都是AMD模块。

答案 1 :(得分:2)

除了@Louis的回答,假设你已经在require.js配置中指定了一堆第三方库,在新的ES6模块中,无论何时导入模块,无论是amd还是es6,你都将成为只要保持导入的模块名称一致就可以了。例如:

这是gulpfile:

gulp.task("es6", function () {
  return gulp.src("modules/newFolder//es6/*.js")
  .pipe(babel({
    "presets": ["es2015"],
    "plugins": ["transform-es2015-modules-amd"] 
     // don't forget to install this plugin
  }))
  .pipe(gulp.dest("modules/newFolder/build"));
});

这是es6文件:

import d3 from 'd3';
import myFunc from 'modules/newFolder/es6module'
// ...

这将编译成这样:

define(['d3', 'modules/newFolder/es6module'], function (_d, _myFunc) {
  'use strict';
   // ...
});

只要编译文件的define(['d3', 'modules/newFolder/es6module'], ...中的模块在原始AMD文件中正常,它就可以在现有的require.js设置下使用,例如压缩文件等。

关于@coderC关于require.js加载器的问题,我在AMD模块中使用i18n!nls/lang,起初我认为在ES6模块中找到替代的AMD插件加载器是一件非常棘手的事情,然后我切换到其他本地化工具,例如i18next。但事实证明这样做是可以的:

import lang from 'i18n!nls/lang';
// import other modules..

因为它将由gulp任务编译为类似:

define(['d3', 'i18n!nls/lang'], function (_d, _lang) {
// ....

这样,我们不必担心require.js加载器。

简而言之,在ES6模块中,如果您想使用现有的AMD插件/模块,您只需要确保编译的文件符合现有的设置。此外,您还可以尝试使用ES6模块捆绑器Rollup捆绑所有新的ES6文件。

希望这对那些试图在项目中集成ES6语法的人有所帮助。

答案 2 :(得分:0)

最新版本的babel进行了一些更改:

首先,GST_PLUGIN_STATIC_REGISTER(openh264);不适用于最新版本的babel。而是使用babel({"modules": "amd"})。 (您需要将该插件作为单独的模块安装在npm中,即使用babel({"plugins": ["@babel/plugin-transform-modules-amd"]})。)

第二,npm install --save-dev @babel/plugin-transform-modules-amd的语法不再接受数组作为第二个参数。而是使用gulp.taskgulp.parallel创建复合任务。

您的gulpfile最终看起来像这样:

gulp.series