组件 按需引入原理

组件 按需引入原理,第1张

import { Button } from 'element-ui'

以Element UI为例,为实现按需引入,需要借助 babel-plugin-component 这个 webpack 插件,并且配置 .babelrc

{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

最终转换成:

var button = require('element-ui/lib/button')
require('element-ui/lib/theme-chalk/button.css')
通过重写路径,精准地引入了对应 lib 下的 Button 组件的 JS 和 CSS 代码了,也就实现了按需引入 Button 组件。

解决组件依赖产生的冗余

由于支持每个组件可以单独引入,那么如果产生了组件依赖并且同时按需引入的时候,会产生重复引入。举个例子,在 element-ui 中,Table 组件依赖了 CheckBox 组件,那么当我同时引入了 Table 组件和 CheckBox 组件的时候,最终引入的包会有 2 份 CheckBox 的代码

解决方式:

解决js冗余:通过webpack配置externals,防止将这些 import 的包打包到 bundle 中,并在运行时再去从外部获取这些扩展依赖
//element ui的方式
var externals = {};

Object.keys(Components).forEach(function(key) {
  externals[`element-ui/packages/${key}`] = `element-ui/lib/${key}`;
});

externals['element-ui/src/locale'] = 'element-ui/lib/locale';
utilsList.forEach(function(file) {
  file = path.basename(file, '.js');
  externals[`element-ui/src/utils/${file}`] = `element-ui/lib/utils/${file}`;
});
mixinsList.forEach(function(file) {
  file = path.basename(file, '.js');
  externals[`element-ui/src/mixins/${file}`] = `element-ui/lib/mixins/${file}`;
});
transitionList.forEach(function(file) {
  file = path.basename(file, '.js');
  externals[`element-ui/src/transitions/${file}`] = `element-ui/lib/transitions/${file}`;
});

externals = [Object.assign({
  vue: 'vue'
}, externals), nodeExternals()];

解决css冗余:对于css部分,用后编译的思想(可以解决按需引入的 JS 和 CSS),即依赖包提供源码,而编译交给应用处理 后编译:指的是应用依赖的 NPM 包并不需要在发布前编译,而是随着应用编译打包的时候一块编译。后编译嵌套问题:后编译的包所依赖的包也需要显示指定在inlcude中才行,为了解决这个问题,通过这个插件webpack-post-compile-plugin个人理解:后编译使得编译时机推后,统一编译,使得只编译一次,而不会多次编译产生多份代码。
// webpack.config.js
module.exports = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.js$/,
        loader: 'babel-loader',
        // 注意这里的 include
        // 只需要把后编译的模块 A 和 B 通过 webpack 的 include 配置包含进来即可
        // 除了 src 还包含了额外的 node_modules 下的两个包
        include: [
            resolve('src'),
            resolve('node_modules/A'),
            resolve('node_modules/B')
          ]
      },
      // ...
    ]
  },
  // ...
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1322063.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存