简体   繁体   English

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

[英]Import existing AMD module into ES6 module

I have an existing application where I have AMD modules defined using RequireJS . 我有一个现有的应用程序,我使用RequireJS定义AMD模块。 I use "text" and "i18n" plugins for requirejs extensively in my project. 我在我的项目中广泛使用了“text”和“i18n”插件for requirejs。 I have been experimenting with ES6 modules lately and would like to use them while creating new modules in my application. 我最近一直在试验ES6模块,并希望在我的应用程序中创建新模块时使用它们。 However, I want to reuse the existing AMD modules and import them while defining my ES6 modules. 但是,我想重用现有的AMD模块并在定义我的ES6模块时导入它们。

Is this even possible? 这甚至可能吗? I know Traceur and Babel can create AMD modules from ES6 modules, but that only works for new modules with no dependency on existing AMD modules, but I could not find an example of reusing the existing AMD modules. 我知道Traceur和Babel可以从ES6模块创建AMD模块,但这仅适用于不依赖于现有AMD模块的新模块,但我找不到重用现有AMD模块的示例。

Any help will be appreciated. 任何帮助将不胜感激。 This is a blocker for me right now to start using all ES6 goodies. 这对我来说是一个阻止我开始使用所有ES6好东西。

Thanks 谢谢

Yes, it can be done. 是的,可以做到。 Create a new application with the following structure: 使用以下结构创建新应用程序:

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

Install gulp and gulp-babel . 安装gulpgulp-babel (I prefer to install gulp locally but you may want it globally: that's up to you.) (我更喜欢在本地安装gulp ,但你可能想要全局:这取决于你。)

index.html : 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 : 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 : js/foo.js

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

js/main.es6 : js/main.es6

import foo from "foo";

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

After you've run gulp to build the application, open the file build/index.html in your browser. 在运行gulp构建应用程序之后,在浏览器中打开文件build/index.html You'll see on the console: 你会在控制台上看到:

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

The ES6 module main was able to load the AMD module foo and use the exported value. ES6模块main能够加载AMD模块foo并使用导出的值。 It would also be possible to have a native-AMD module load an ES6 module that has been converted to AMD. 也可以让本机AMD模块加载已转换为AMD的ES6模块。 Once Babel has done its work, they are all AMD modules as far as an AMD loader is concerned. 一旦Babel完成了它的工作,就AMD装载机而言,它们都是AMD模块。

In addition to @Louis's answer, assuming you already have a bunch of third party libraries specified in require.js configuration, in your new ES6 modules, whenever you are importing a module, be it amd or es6, you'll be fine as long as you keep the imported module name consistent. 除了@Louis的答案之外,假设你已经在require.js配置中指定了一堆第三方库,在新的ES6模块中,无论何时导入模块,无论是amd还是es6,你都可以。因为您保持导入的模块名称一致。 For example: 例如:

Here is the gulpfile: 这是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"));
});

Here is the es6 file: 这是es6文件:

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

This will be compiled to sth like this: 这将编译为这样:

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

as long as the module in define(['d3', 'modules/newFolder/es6module'], ... of the compiled file is fine in a original AMD file, it should work with under existing require.js setup, such as compress files etc. 只要编译文件的define(['d3', 'modules/newFolder/es6module'], ...中的define(['d3', 'modules/newFolder/es6module'], ...在原始AMD文件中正常,它应该在现有的require.js设置下工作,例如压缩文件等

In terms of @coderC's question about require.js loaders, I was using i18n!nls/lang in AMD modules, at first I thought it would be a really tricky thing to find an alternative of AMD plugin loaders in ES6 modules, and I switched to other localization tools such as i18next . 关于@coderC关于require.js加载器的问题,我在AMD模块中使用了i18n!nls/lang ,起初我认为在ES6模块中找到AMD插件加载器的替代方案是非常棘手的,我切换了到其他本地化工具,如i18next But it turned out that it's okay to do this: 但事实证明这样做是可以的:

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

because it will be compiled by gulp task to sth like: 因为它将由gulp任务编译为......

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

This way, we don't have to worry about the require.js loader. 这样,我们就不必担心require.js加载器了。

In a nutshell, in ES6 modules, if you want to use existing AMD plugin/modules, you just need to ensure the compiled file is conformed with the existing setup. 简而言之,在ES6模块中,如果您想使用现有的AMD插件/模块,您只需要确保编译的文件符合现有的设置。 Additionally, you can also try the ES6 module bundler Rollup to bundle all the new ES6 files. 此外,您还可以尝试使用ES6模块捆绑器Rollup捆绑所有新的ES6文件。

Hope this can be helpful for those who are trying to integrate ES6 syntax in project. 希望这对那些试图在项目中集成ES6语法的人有所帮助。

A few changes for the latest version of babel: 最新版babel的一些变化:

First, babel({"modules": "amd"}) doesn't work with the latest version of babel. 首先, babel({"modules": "amd"})不适用于最新版本的babel。 Instead, use babel({"plugins": ["@babel/plugin-transform-modules-amd"]}) . 相反,使用babel({"plugins": ["@babel/plugin-transform-modules-amd"]}) (You'll need to install that plugin as a separate module in npm, ie with npm install --save-dev @babel/plugin-transform-modules-amd .) (您需要在npm中将该插件作为单独的模块npm install --save-dev @babel/plugin-transform-modules-amd ,即使用npm install --save-dev @babel/plugin-transform-modules-amd 。)

Second, the syntax for gulp.task no longer accepts arrays as its second argument. 其次, gulp.task的语法不再接受数组作为其第二个参数。 Instead, use gulp.parallel or gulp.series to create a compound task. 相反,使用gulp.parallelgulp.series创建复合任务。

Your gulpfile will end up looking like this: 你的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"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM