如何使基于 class 的自定义元素无副作用,以便 webpack 仅捆绑显式导入的组件
How to make a class-based custom element side-effect-free so webpack only bundles the explicitly imported components
我有一组 spec v1 自定义元素,我正在使用 webpack 4 进行捆绑(并使用 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' });
现在为了能够使用选择性的命名导入从这些组件创建自定义包,我需要将这些文件标记为 side-effect-free。
不过,组件注册发生在模块本身:
customElements.define('comp-div', CompDiv, { extends: 'div' });
据我了解,是副作用。
现在我有一个 index.js
基本上是这样的:
export { CompDiv } from './components/comp-div/comp-div';
...
export { CompBtn } from './components/comp-btn/comp-btn';
我的 webpack 入口点是这样的:
import 'document-register-element';
import 'babel-polyfill';
import { CompDiv } from './index';
现在,当我这样做时,CompBtn
(以及 index.js 中的所有其他导出)最终成为包的一部分,即使它没有导入到我的 webpack 入口点。
允许使用这些 Web 组件在 webpack 中进行摇树优化的推荐方法是什么?
来自 webpack 指南 - Mark the file as side-effect-free:
All the code noted above does not contain side effects, so we can simply mark the property as false to inform webpack that it can safely prune unused exports.
因此,在 package.json
中设置 "sideEffects": false
告诉 webpack 您的模块没有副作用。这样它就可以修剪未使用的导出(在您的情况下,未使用 re-exports)。这通常由 库作者.
使用
但这只是等式的一方面。
来自 webpack 配置文档 - optimization.sideEffects
:
Tells webpack to recognise the sideEffects
flag in package.json
or rules to skip over modules which are flagged to contain no side effects when exports are not used.
因此,为了利用前面提到的选项,库消费者 必须在他们的 webpack 配置中将 optimization.sideEffects
选项设置为 true
文件:
// webpack.config.js
module.exports = {
...
optimization: {
sideEffects: true
}
...
}
请注意,在 production
mode 中,此选项默认启用。因此,您只需将其设置为 development
模式。
N.B.:在这种情况下,您既是作者又是消费者 你的模块。
最后,让我们看看您的 webpack 入口点:
// webpack entrypoint
import 'document-register-element';
import 'babel-polyfill';
import { CompDiv } from './index';
如果您稍后在此文件中不使用导入的 CompDiv
,webpack 将对其进行修剪 - 假设您已在 package.json
和 optimization.sideEffects
中设置 "sideEffects": false
在你的 webpack 配置中 true
。
但是,例如,即使您 仅 导入了 'babel-polyfill'
并且稍后不会在此文件中显式使用它的任何内容,webpack 也不会修剪它,因为 babel-polyfill
库的 package.json
不包含 "sideEffects": false
.
我希望事情已经解决了。
我有一组 spec v1 自定义元素,我正在使用 webpack 4 进行捆绑(并使用 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' });
现在为了能够使用选择性的命名导入从这些组件创建自定义包,我需要将这些文件标记为 side-effect-free。
不过,组件注册发生在模块本身:
customElements.define('comp-div', CompDiv, { extends: 'div' });
据我了解,是副作用。
现在我有一个 index.js
基本上是这样的:
export { CompDiv } from './components/comp-div/comp-div';
...
export { CompBtn } from './components/comp-btn/comp-btn';
我的 webpack 入口点是这样的:
import 'document-register-element';
import 'babel-polyfill';
import { CompDiv } from './index';
现在,当我这样做时,CompBtn
(以及 index.js 中的所有其他导出)最终成为包的一部分,即使它没有导入到我的 webpack 入口点。
允许使用这些 Web 组件在 webpack 中进行摇树优化的推荐方法是什么?
来自 webpack 指南 - Mark the file as side-effect-free:
All the code noted above does not contain side effects, so we can simply mark the property as false to inform webpack that it can safely prune unused exports.
因此,在 package.json
中设置 "sideEffects": false
告诉 webpack 您的模块没有副作用。这样它就可以修剪未使用的导出(在您的情况下,未使用 re-exports)。这通常由 库作者.
但这只是等式的一方面。
来自 webpack 配置文档 - optimization.sideEffects
:
Tells webpack to recognise the
sideEffects
flag inpackage.json
or rules to skip over modules which are flagged to contain no side effects when exports are not used.
因此,为了利用前面提到的选项,库消费者 必须在他们的 webpack 配置中将 optimization.sideEffects
选项设置为 true
文件:
// webpack.config.js
module.exports = {
...
optimization: {
sideEffects: true
}
...
}
请注意,在 production
mode 中,此选项默认启用。因此,您只需将其设置为 development
模式。
N.B.:在这种情况下,您既是作者又是消费者 你的模块。
最后,让我们看看您的 webpack 入口点:
// webpack entrypoint
import 'document-register-element';
import 'babel-polyfill';
import { CompDiv } from './index';
如果您稍后在此文件中不使用导入的 CompDiv
,webpack 将对其进行修剪 - 假设您已在 package.json
和 optimization.sideEffects
中设置 "sideEffects": false
在你的 webpack 配置中 true
。
但是,例如,即使您 仅 导入了 'babel-polyfill'
并且稍后不会在此文件中显式使用它的任何内容,webpack 也不会修剪它,因为 babel-polyfill
库的 package.json
不包含 "sideEffects": false
.
我希望事情已经解决了。