【问题标题】:ES6 Dynamic Imports using Webpack and Babel使用 Webpack 和 Babel 的 ES6 动态导入
【发布时间】:2018-02-16 13:18:38
【问题描述】:

我一直在我的 ES6 JS 项目中使用 Webpack,并且一直运行良好,直到我开始使用动态导入。

我所做的工作(router.js):

import { navigo } from "Navigo"; // router
import { clients } from "Controllers/clients.js";

const navigo = new Navigo();

navigo_router.on({
  '/clients': () => {
    clients.init();
  }
});

但是我添加的页面/路由越多,模块头部的导入就越多。这是一个相对较大的应用程序,我有很多页面/路由要添加,因此我需要动态加载它们以减少初始页面加载的大小。

所以,在Webpack's documentation for dynamic imports 之后,我尝试了以下方法,它在调用相对路由时 加载控制器模块:

import { navigo } from "Navigo"; // router

const navigo = new Navigo();

navigo_router.on({
  '/clients': () => {
    import("Controllers/clients.js").then((clients) => {
      clients.init();
    });
  }
});

但是将它保存在我的编辑器中会导致 Babel 编译错误; SyntaxError: 'import' and 'export' 可能只出现在顶层,在浏览器中测试时不会调用clients.init()

经过一番阅读,我发现我需要一个 Babel plugin 来将动态 import() 转换为 require.ensure。因此,我使用以下命令安装了插件:

npm install babel-plugin-dynamic-import-webpack --save-dev

并在我的babel.rc 文件中声明了插件

{ "plugins": ["dynamic-import-webpack"] }

安装插件后,转译错误消失了,检查我转译的代码我发现动态import()s实际上已按预期更改为require.ensure。但是现在我在测试时遇到以下浏览器错误:

Error: Loading chunk 0 failed.
Stack trace:
u@https://<mydomain.com>/js/app.bundle.js:1:871
SyntaxError: expected expression, got '<' 0.app.bundle.js:1
Error: Loading chunk 0 failed.

我不明白为什么它引用带有 0. 前缀的 0.app.bundle.js,所以我检查了我的 output/dist 文件夹,现在我有一个名为 0.app.bundle.js 的新文件:

0.app.bundle.js      1,962bytes
app.bundle.js        110,656bytes

我想这个新的捆绑文件是动态导入的模块,clients.js

我只为那条路线添加了动态导入,而其他所有路线都保持原样。因此,在测试过程中,我可以查看除 /clients 路由之外的所有路由,该路由现在会引发上述错误。

此时我完全迷失了方向,希望有人能帮助我越过终点线。这个新文件0.app.bundle.js 是什么?我应该如何使用它/将它包含在我的应用程序中?

我希望我已经足够清楚地解释了自己,并期待任何回应。

【问题讨论】:

  • 当其他东西(JSON、JavaScript、CSS 等)被预期时,该特定错误几乎总是来自服务 HTML 的服务器。

标签: javascript webpack ecmascript-6 babeljs es6-modules


【解决方案1】:

我最终设法解决了自己的问题,所以我将在答案中分享我的发现。

块文件未加载的原因是 Webpack 在错误的目录中查找它。我注意到在我的开发人员控制台的网络选项卡中,块文件/模块是从我的根目录 / 而不是在它所属的 /js 目录中调用的。

根据 Webpack 的文档,我在我的 Webpack 配置文件中添加了以下内容:

output: {
  path: path.resolve(__dirname, 'dist/js'),
  publicPath: "/js/", //<---------------- added this
  filename: 'app.bundle.js'
},

据我了解,path 用于 Webpack 的静态模块,publicPath 用于动态模块。

这使得块加载正确,但我还有其他问题需要处理,因为 client.init() 没有被调用并产生以下错误:

TypeError: e.init is not a function

为了解决这个问题,我也不得不改变:

import("Controllers/clients.js").then((clients) => {
  clients.init();
});

收件人:

import("Controllers/clients.js").then(({clients}) => {
  clients.init();
});

注意箭头函数参数中的花括号。

我希望这对其他人有帮助。

【讨论】:

  • 我已经尝试过你提到的但得到以下错误:bundle.js:106 Uncaught (in promise) ChunkLoadError: Loading chunk 0 failed. (error: http://localhost:3000/js/src/app/0.bundle.js)。你能检查一下这个stackoverflow.com/questions/60056219/…
【解决方案2】:

为了调试,你需要做

import("Controllers/clients.js").then((clients) => {
    console.log(clients);
});

也许工作

import("Controllers/clients.js").then((clients) => {
    clients.default.init();
});

【讨论】:

    猜你喜欢
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    • 2016-09-26
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多