【问题标题】:Webpack 4 is tree shaking away bootstrap, how can I prevent that?Webpack 4 正在摇树引导,我该如何防止呢?
【发布时间】:2019-02-26 08:40:49
【问题描述】:

我正在尝试获取一个使用 Jquery 模态插件的旧版应用程序,该插件需要引导程序的 javascript 才能在使用自定义 Webpack 配置的 Angular 6 和 Webpack 4 项目中工作。一切正常,除了捆绑期间发生的摇树正在删除我的vendor.ts 文件中的引导导入,因为我在我的应用程序中没有明确使用引导导入。

这会导致我的引导模式和引导下拉菜单中断。

注意:如果我添加类似:

import * as bootstrap from "bootstrap";
console.log(bootstrap);

对于我的main.ts 文件,webpack 不会删除引导程序并且一切正常。

我已经尝试向the documentation 中建议的package.json sideEffects 属性添加多个条目,但我认为此属性用于标记应该删除的代码。有没有办法将导入的模块标记为从摇树过程中删除?

我也尝试过这样的 ProvidePlugin:

new ProvidePlugin({
    $: "jquery",
    jQuery: "jquery",
    "window.jQuery": "jquery",
    _: "underscore",
    bootstrap: "bootstrap",
    moment: "moment",
    momenttimezone: "moment-timezone",
    // Collapse: "exports-loader?Collapse!bootstrap/js/dist/collapse",
    // Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown",
    Modal: "exports-loader?Modal!bootstrap/js/dist/modal",
})

感谢您的宝贵时间。

【问题讨论】:

    标签: javascript angular webpack tree-shaking


    【解决方案1】:

    我遇到了同样的问题,解决方法如下:

    不要使用“import”,而是使用“require”。

    改变这个

    import * as bootstrap from "bootstrap";
    

    到这里

    require("bootstrap");
    

    不幸的是,我还没有弄清楚如何使它与“导入”一起使用。

    【讨论】:

    • 在下面查看我的答案,看看如何让它与导入一起使用。
    • 我认为这实际上是 webpack tree 摇出来的,在类似的情况下也有同样的问题。
    【解决方案2】:

    在对这个问题进行了更多研究之后,我遇到了与其他导入类似的问题,根本问题是我在不止一个地方引用了第三方库。

    换句话说,我在我的main.tsvendor.ts 和我的ProvidePlugin 中导入了 JQuery、bootstrap 和其他库。捆绑应用后,不同的引用相互冲突,这导致我的应用出现问题。

    我首先清理了所有引用并将它们全部放在一个地方,ProvidePlugin。然后我还将 runtimeChunk 添加到我的 webpack 配置中。

    optimization: {
        runtimeChunk: "single"
    }
    

    这可确保所有代码都引用相同的库。查看文档here。我将把答案留给@hostar,因为他确实解决了我最初的问题。

    【讨论】:

    • 这很有趣,我刚刚阅读了 webpack 核心成员之一的评论,说除非需要,否则不应使用 runtimeChunk。 See this comment。一旦我的 angularJS 应用程序完全转换为 Angular,我们应该能够删除所有这些第三方库,所以理想情况下这是一个短期修复。
    • 很高兴找到@justin!从几个地方引用相同的库应该不是问题,webpack 足够聪明地发现它是同一件事。使用 optimization.splitChunks webpack 将只包含该库一次并在模块中创建所需的引用。我认为这可能是 webpack 中的错误,因为使用“runtimeChunk”似乎过于复杂。
    【解决方案3】:

    在你的 webpack 配置中尝试webpack.ProvidePlugin

    自动加载模块,而不必importrequire 他们无处不在。

    例子:

    // In webpack config
    ...
    plugins: [
      new webpack.ProvidePlugin({
        bootstrap: 'bootstrap'
      })
    ]
    ...
    

    More info about "shimming" in the documentation.

    【讨论】:

    • 我也尝试过,甚至尝试提供特定的引导模块,如 this article 中所建议的那样。
    【解决方案4】:

    从 Bootstrap 4.5 版开始,我认为更好的解决方案是明确说明您正在使用的插件,如 in the documentation 所述:

    import 'bootstrap/js/dist/util';
    import 'bootstrap/js/dist/modal';
    

    通过这种方式,您不会加载完整的引导 js,而只会加载您需要的内容。 Afaik,如果您使用它,则无需使用 ProvidePlugin 将 bootstrap 设置为全局,也不需要特殊的 tree-shaking 配置。

    另外,如果您使用 jQuery 进行 Bootstrap,则无需为 jQuery 进行特殊配置。 bootstrap/js/dist/util.js 已经完成了 import $ "from jquery",所以 webpack 将处理导入。

    如果您更喜欢使用jquery-slim 而不是“jquery”,请创建一个别名,这样import "jquery" 将被解析为 slim 模块。事实上,我总是配置指向完整版或精简版的别名。我发现这样可以避免意外两次导入jQuery之类的问题..

    resolve: {
        alias: {
            // or "jquery/dist/jquery.js" for the full version
            jquery: 'jquery/dist/jquery.slim.js',
        }
    },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-24
      • 2018-08-30
      • 2016-11-12
      • 2018-09-10
      • 2019-05-08
      • 2019-10-15
      • 1970-01-01
      • 2011-10-16
      相关资源
      最近更新 更多