【问题标题】:Accessing webpack bundled libraries in the browser在浏览器中访问 webpack 捆绑的库
【发布时间】:2017-02-02 22:31:25
【问题描述】:

我在从浏览器访问 webpack 捆绑库时遇到问题。

示例:我有一个班级Foo

// foo.js

"use strict";

export default class Foo {
  constructor() {
    var bar = "bar";
  }
}

Foo 导入到src.js

// src.js

"use strict";
import Foo from "./foo.js";

webpack 配置如下所示。入口为src.js,输出文件为bundle.js

// webpack.config.js

module.exports = {
  entry: './src.js',
  output: {
    path: '.',
    filename: 'bundle.js',
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015']
        }
      },
    ]
  },
};

Webpack 编译一切正常,我可以将其加载到我的 HTML 文件中。

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <script src="bundle.js"></script>
  <script type="text/javascript">
    var x = new Foo();
    console.log(x);
  </script>
</head>
<body>
</body>
</html>

正是在这一点上,我得到了错误。出于某种原因,捆绑的 JS 没有将 Foo 类放入浏览器能够访问的命名空间中。

这是我在 Firefox 中遇到的错误:

ReferenceError: Foo is not defined[Learn More]

WebPack 中有一些配置我没有摸索,我很确定,但到目前为止我还没有弄明白。

【问题讨论】:

  • 这是设计使然。
  • @Claies 我无法访问我想包含在包中的类是设计使然吗?那么 webpack 的意义何在?
  • 在设计上,对象的范围仅限于导入它们的模块,尤其是在使用严格模式时。 src.js 中的导入与 HTML 中的脚本不在同一范围内,因为该脚本是 1) 未处于严格模式 2) 绑定到全局命名空间。
  • 好的,但是我在文档、博客文章或下面解释如何获取我正在编写的代码的答案中没有看到任何地方。我需要以某种方式到达 Foo() 并且没有什么可以解释如何做到这一点。只是我做错了。
  • 如果您在src.js 中编写使用该导入的代码,它会正常运行并且您不会有任何ReferenceError。但是,浏览器本身并不支持类;支持是通过 babel 添加的。但是,babel 不会转译您的 &lt;script&gt; 标签。如果您想在&lt;script&gt; 标签中使用该类,那么将其导出到全局命名空间是您唯一的选择。这不是 WebPack 本身就“完成”的事情,而且通常也不是好的编程实践。

标签: javascript webpack babeljs


【解决方案1】:

要使这段代码可重用,你需要告诉 webpack 你正在编写一个库。

来自 webpack documentation:

要使您的库可供重用,请在 webpack 配置中添加库属性。

要创建您的库,请进行以下更改:

module.exports = {
  entry: './src.js',
  output: {
    path: '.',
    filename: 'bundle.js',
    library: 'fooLibrary', //add this line to enable re-use
  },
...

为了使用该库,您可以在其他脚本中引用它:

<script type="text/javascript">
  var x = new fooLibrary.Foo();
  console.log(x);
</script>

【讨论】:

  • 为了使用库,你必须在生产中构建它,停止开发服务器按 ctrl + C 并输入 webpack -p (build for production
【解决方案2】:

看起来 'var' 是 output.libraryTarget 的默认值,因此您应该能够定义您的 output.library 属性,并且您将能够全局访问 var。 https://webpack.js.org/configuration/output/#output-librarytarget

【讨论】:

    【解决方案3】:

    Webpack 和 ES2015 模块的主要优点之一是它默认停止污染全局命名空间。

    因此,如果您想在全局对象上发布某些内容,则必须明确地执行此操作。我建议将您的类命名为应用程序或公司独有的名称,这样您就不会冒与其他任何东西发生命名冲突的风险。

    【讨论】:

    • 我不想污染命名空间——这就是我创建一个类的原因——我只是想弄清楚如何访问那个类。我在文档中找不到有关如何执行此操作的任何内容。
    猜你喜欢
    • 1970-01-01
    • 2019-04-04
    • 2020-01-18
    • 2017-08-04
    • 1970-01-01
    • 2017-09-03
    • 2016-10-12
    • 2019-07-10
    • 1970-01-01
    相关资源
    最近更新 更多