如何使基于类的自定义元素无副作用,因此webpack仅捆绑显式导入的组件

con*_*exo 12 javascript webpack es6-modules tree-shaking

我有一组使用vpack 4捆绑在一起的spec v1自定义元素(和babel-loader进行转换)。

所有组件看起来都与此类似:

export class CompDiv extends HTMLDivElement {
  constructor(...args) {
    const self = super(...args);
    self.property = null;
    return self;
  }
  connectedCallback() {
    console.log('connected CompDiv');
  }
}

customElements.define('comp-div', CompDiv, { extends: 'div' });
Run Code Online (Sandbox Code Playgroud)

现在,要能够使用选择性的命名导入从这些组件创建自定义程序包,我需要将这些文件标记为没有副作用

但是,组件注册发生在模块本身中:

customElements.define('comp-div', CompDiv, { extends: 'div' });
Run Code Online (Sandbox Code Playgroud)

据我了解,这一个副作用。

现在我有一个index.js基本上看起来像这样的:

export { CompDiv } from './components/comp-div/comp-div';
...
export { CompBtn } from './components/comp-btn/comp-btn';
Run Code Online (Sandbox Code Playgroud)

我的webpack入口点如下所示:

import 'document-register-element';
import 'babel-polyfill';
import { CompDiv } from './index';
Run Code Online (Sandbox Code Playgroud)

现在,当我执行此操作时CompBtn(以及未将其导入到我的webpack入口点中),(以及index.js中的所有其他导出结果)最终成为捆绑包的一部分。

建议使用这些Web组件在webpack中进行树状握手的推荐方法是什么?

小智 5

来自 webpack 指南 -将文件标记为无副作用

上面提到的所有代码都不包含副作用,因此我们可以简单地将属性标记为 false 来通知 webpack 它可以安全地修剪未使用的导出

因此,设置"sideEffects": false告诉package.jsonwebpack 你的模块没有副作用。这样它就可以修剪未使用的导出(在您的情况下,未使用的再导出)。这通常由库作者使用。

但这只是等式的一方面。

来自 webpack 配置文档 - optimization.sideEffects

告诉 webpack 识别或规则sideEffects中的标志package.json,以跳过在不使用导出时标记为不包含副作用的模块。

因此,为了利用前面提到的选项,库使用者必须在其 webpack 配置文件中设置该optimization.sideEffects选项:true

// webpack.config.js
module.exports = {
  ...
  optimization: {
    sideEffects: true
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,在productionmode下,此选项默认启用。因此,您只需将其设置为development模式即可。

注意:在这种情况下,您既是模块的作者又是模块的使用者。

最后,让我们看看您的 webpack 入口点:

// webpack entrypoint
import 'document-register-element';
import 'babel-polyfill';
import { CompDiv } from './index';

Run Code Online (Sandbox Code Playgroud)

CompDiv如果您稍后不在此文件中使用导入的内容,webpack 会删除它 - 假设您已在 webpack 配置中设置了"sideEffects": falseinpackage.jsonoptimization.sideEffectsto 。true

但是,例如,即使您导入'babel-polyfill'并且稍后不会在此文件中显式使用其中的任何内容,webpack 也不会删除它,因为package.jsonforbabel-polyfill库不包含"sideEffects": false.

我希望事情能够澄清。