如何使基于类的自定义元素无副作用,因此webpack仅捆绑显式导入的组件 [英] How to make a class-based custom element side-effect-free so webpack only bundles the explicitly imported components

查看:77
本文介绍了如何使基于类的自定义元素无副作用,因此webpack仅捆绑显式导入的组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组规范v1自定义元素,我正在使用webpack 4进行捆绑(并使用babel-loader进行转换)。



这些组件看上去都很相似

  export class CompDiv扩展HTMLDivElement {
构造函数(... args){
const自我= super(... args);
self.property = null;
返回自我;
}
connectedCallback(){
console.log(’connected CompDiv’);
}
}

customElements.define('comp-div',CompDiv,{扩展名:'div'});

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



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

  customElements.define('comp-div',CompDiv,{扩展名:'div'}); 

据我了解,的副作用。



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

 从 ./components/comp-div/comp-div导出{CompDiv}; 
...
从‘./components/comp-btn/comp-btn’中导出{CompBtn};

我的webpack入口点如下:

  import'document-register-element'; 
导入 babel-polyfill;从'./index'中导入
{CompDiv};

现在,当我这样做时, CompBtn (以及index.js中的所有其他导出)最终都成为捆绑包的一部分,即使它没有导入到我的webpack入口点中。



推荐的允许方式是

解决方案

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


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


因此,将 sideEffects设置为:false package.json 告诉webpack您的模块没有副作用。这样就可以修剪未使用的出口(在您的情况下为未使用的再出口)。

但这只是等式的一方面。



来自webpack配置文档- optimization.sideEffects


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


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

  // webpack .config.js 
mo dule.exports = {
...
优化:{
sideEffects:true
}
...
}

请注意,在 生产模式,默认情况下启用此选项。因此,您只需要将其设置为开发模式。



NB :在这种情况下,您既是模块的 author 也是 consumer



最后,让我们来看一下在您的Webpack入口点:

  // webpack入口点
import'document-register-元件';
导入 babel-polyfill;从'./index'中导入
{CompDiv};

如果您不使用导入的 CompDiv 在此文件的后面,webpack将对其进行修剪-假设您已在 package.json中设置了 sideEffects:false code>和 optimization.sideEffects 到Webpack配置中的 true



但是,例如,即使您仅导入了'babel-polyfill',也不会明确使用稍后在此文件中,webpack不会对其进行修剪,因为 babel-polyfill 库的 package.json 不会' t包含 sideEffects:false



我希望可以解决问题。


I have a set of spec v1 custom elements which I'm using webpack 4 to bundle (and babel-loader to transpile).

The components all look similar to this:

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' });

Now to be able to create custom packages from these components using selective, named imports I need to mark these files as side-effect-free.

The component registration, though, takes place in the module itself:

customElements.define('comp-div', CompDiv, { extends: 'div' });

As far as I understand, that is a sideeffect.

Now I have an index.js that basically looks like this:

export { CompDiv } from './components/comp-div/comp-div';
...
export { CompBtn } from './components/comp-btn/comp-btn';

My webpack entry point looks like this:

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

Now when I do this, CompBtn (and all other exports in index.js) ends up being part of the bundle even though it's not imported in my webpack entry point.

What would be the recommended way of allowing for treeshaking in webpack with these web components?

解决方案

From webpack guide - 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.

So, setting "sideEffects": false in package.json tells webpack that your modules are side effect free. So that it can prune unused exports (in your case, unused re-exports). This is generally used by library authors.

But that's just one side of the equation.

From webpack configuration docs - 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.

So, in order to leverage that previously mentioned option, the library consumer will have to set the optimization.sideEffects option to true in their webpack config file:

// webpack.config.js
module.exports = {
  ...
  optimization: {
    sideEffects: true
  }
  ...
}

Note that, in production mode, this option is enabled by default. So, you'll only need to set it for development mode.

N.B.: In this case, you are both the author and the consumer of your modules.

Lastly, let's look at your webpack entrypoint:

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

If you don't use your imported CompDiv later in this file, webpack will prune it - assuming you've set "sideEffects": false in package.json and optimization.sideEffects to true in your webpack config.

But, for example, even if you only imported 'babel-polyfill' and won't explicitly use anything from it later in this file, webpack will not prune it, because the package.json for babel-polyfill library doesn't contain "sideEffects": false.

I hope that clears things up.

这篇关于如何使基于类的自定义元素无副作用,因此webpack仅捆绑显式导入的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆