Vue 2.x TypeScript 按需引入element-ui

在业务中,只要使用组件库,就不可避免的要涉及到按需引入的问题,尤其是element这种重量级的组件库,如果一次性全部引入,对整个项目的大小影响很大。但是,element官方只提供了基于babel的按需引入方案(babel-plugin-component),并没有给出ts应该如何做到按需引入。

经过试验,如果不做处理,哪怕是import { Button, Select } from 'element-ui';,在ts中还是会全部引入。

本来是之前是没什么好办法的,只能额外引入babel,先将ts编译成ES6的JS,再通过babel进行一次处理,但是上次用vant-ui的时候,看到他们官方推荐的一个插件很有意思, ts-import-plugin。按照作者的说法,这个插件是babel-plugin-component的ts实现,看了看文档似乎也是支持element-ui的:

// webpack.config.js
const tsImportPluginFactory = require('ts-import-plugin')

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(jsx|tsx|js|ts)$/,
        loader: 'ts-loader',
        options: {
          transpileOnly: true,
          getCustomTransformers: () => ({
            before: [ tsImportPluginFactory( /** options */) ]
          }),
          compilerOptions: {
            module: 'es2015'
          }
        },
        exclude: /node_modules/
      }
    ]
  },
  // ...
}

transformerFactory({
    libraryName: 'element-ui',
    libraryDirectory: 'lib',
    camel2DashComponentName: true,
    style: (path: string) =>
        join('element-ui', 'lib', 'theme-chalk', `${
            camel2Dash(basename(path, '.js'))}.css`),
})

看起来是没啥问题的。但是真正用起来,里面有两个小问题:

  1. 文档前面的tsImportPluginFactory和后面的transformerFactory是不是一个东西?经过试验,确实是一个东西。

  2. 如果直接复制上面的代码,会报错join、camel2Dash、basename未定义。并且作者也没有在文档上写明白这一点。事实上,这是额外引入了两个库:

    const path = require("path");
    const join = path.join;
    const basename = path.basename;
    const camel2Dash = require("camel-2-dash");
    

解决了上面两个问题,就可以按照import { Button, Select } from 'element-ui';的方式进行按需引入了。

因为我这个场景是Vue,vue-cli的配置有一点区别,因为vue-cli基于webpack-chain,所以语法和标准的webpack还不太一样,需要一些额外的处理。在根目录下创建一个vue.config.js,然后把上面的内容改造一下:

// vue.config.js
const path = require("path");
const tsImportPluginFactory = require("ts-import-plugin");
const join = path.join;
const basename = path.basename;
const camel2Dash = require("camel-2-dash");

module.exports = {
  chainWebpack: config => {
    config.module
      .rule("ts")
      .use("ts-loader")
      .tap(options => {
        options = merge(options, {
          transpileOnly: true,
          getCustomTransformers: () => ({
            before: [
              tsImportPluginFactory({
                libraryName: "element-ui",
                libraryDirectory: "lib",
                camel2DashComponentName: true,
                style: path =>
                  join(
                    "element-ui",
                    "lib",
                    "theme-chalk",
                    `${camel2Dash(basename(path, ".js"))}.css`
                  )
              })
            ]
          }),
          compilerOptions: {
            module: "es2015"
          }
        });
        return options;
      });
  }
};

这样就可以和Vue联动了。

参考资料

  1. https://element.eleme.cn/#/zh-CN/component/quickstart#an-xu-yin-ru
  2. https://youzan.github.io/vant/?source=vuejsorg#/zh-CN/quickstart#yin-ru-zu-jian
  3. https://github.com/Brooooooklyn/ts-import-plugin#element-ui
  4. https://github.com/Brooooooklyn/ts-import-plugin/issues/29#issuecomment-583895937
发布了110 篇原创文章 · 获赞 132 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/HermitSun/article/details/104637527