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

11
我有一个现有的应用程序,其中我使用RequireJS定义了AMD模块。 我在项目中广泛使用"文本"和"i18n"插件来进行requirejs。 最近我一直在尝试使用ES6模块,并希望在创建新的模块时使用它们。 但是,我想重用现有的AMD模块并在定义我的ES6模块时导入它们。
这是否可能? 我知道Traceur和Babel可以从ES6模块创建AMD模块,但这仅适用于没有依赖于现有AMD模块的新模块,而我找不到重用现有AMD模块的示例。
任何帮助将不胜感激。 这对我开始使用所有ES6好处来说是一个阻碍。
谢谢

1
仅适用于没有依赖现有AMD模块的新模块” - 你为什么这样认为?如果您编译为AMD并使用requirejs加载您的模块,则仍然可以轻松地要求“正常”(未编译)模块。 - Bergi
1
是的,就像@Bergi所说的,您是否计划将ES2015模块编译为除AMD之外的其他内容? - JMM
我想将ES2015模块编译为AMD格式。但是,正如我所提到的,我已经有一些AMD模块,我希望在我的ES2015模块中导入它们,以便我可以重复使用它们,而不必再次编写它们。 - coderC
3个回答

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模块。


非常感谢您的回复。这对于普通的AMD模块是有效的。然而,我一直在使用一些RequireJS插件,它们具有类似require(['text!myTemplate.tpl'], function(MyTemplate){});的格式。这种格式如何与ES2015配合使用? - coderC

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 的问题,我在 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 语法的人有所帮助。

0

babel 最新版本有一些变化:

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

其次,gulp.task 的语法不再接受数组作为第二个参数。请使用 gulp.parallelgulp.series 创建一个复合任务。

您的 gulpfile 将会像这样:

"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({"plugins": ["@babel/plugin-transform-modules-amd"]}))
        .pipe(gulp.dest("build/js"));
});

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接