1、CDN引入(umd 总文件)
2、npm包完整引入(抛出commonjs2总文件)
3、按需引入(抛出commonjs2的所有UI组件)
4、支持国际化
5、提供utils方法(官方文档没有说明,但事实上业务可以使用)
CDN引入的umd总文件一般是全量构建的,不会有依赖问题,但是commonjs2模块的文件需要在业务层面再次使用Webpack构建。例如需要在业务层面支持 国际化 和 提供utils 的功能,那么就不能将 国际化 和 提供utils 的代码 bundle 到 commonjs2总文件 或 commonjs2的所有UI组件 中(每一个组件都 bundle utils 的方法或者国际化API显然是不合理的),如果需要在业务层面支持 按需引入 的功能,那么不建议将 所有UI组件 的源码 bundle 到 commonjs2总文件 中,这样便可以实现层层引用,对外抛出功能的同时在业务层面可以防止Webpack二次打包,从而导致引入两遍甚至多遍相同的代码的问题。
在组件库中开发时,为了构建commonjs2模块的文件,需要对各个 utils 、组件等引入的路径做出强约定,这样不仅产生的Webpack配置会变得很难维护,对于开发者的开发也需要做出一定的规范限制。
接下来分析一下各个脚本的构建功能。
npm run build:file
build:file 脚本是自动生成一些源码文件的脚本:
"build:file": "node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js",
其中与构建相关的脚本是 node build/bin/build-entry.js ,主要用于生成Webpack构建的入口源文件 src/index.js :
// 注释说明该文件由build-entry.js脚本自动生成 /* Automatically generated by './build/bin/build-entry.js' */ import Pagination from '../packages/pagination/index.js'; // ... 这里省略大部分组件引入 import TimelineItem from '../packages/timeline-item/index.js'; import locale from 'element-ui/src/locale'; import CollapseTransition from 'element-ui/src/transitions/collapse-transition'; const components = [ Pagination, // ... 这里省略大部分组件 TimelineItem, CollapseTransition ]; const install = function(Vue, opts = {}) { locale.use(opts.locale); locale.i18n(opts.i18n); components.forEach(component => { Vue.component(component.name, component); }); Vue.use(Loading.directive); Vue.prototype.$ELEMENT = { size: opts.size || '', zIndex: opts.zIndex || 2000 }; Vue.prototype.$loading = Loading.service; // ... }; /* istanbul ignore if */ if (typeof window !== 'undefined' && window.Vue) { install(window.Vue); } export default { version: '2.7.0', locale: locale.use, i18n: locale.i18n, install, CollapseTransition, Loading, Pagination, // ... 这里省略大部分组件 TimelineItem };
在组件的开发过程中如果组件较多,建议使用脚本自动生成构建入口文件。
npm run lint
构建之前使用 lint 脚本对构建的源码文件进行 eslint 校验:
"lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet",
Element 对 eslint 做了严格控制,一旦 eslint 报错那么 dist 总体构建脚本 执行停止,整体构建失败。这里的 eslint 校验可以使用eslint-loader 进行处理(如果你希望 eslint 校验失败也可以进行构建可以查看)。
webpack --config build/webpack.conf.js
webpack --config build/webpack.conf.js 脚本用于构建umd总文件,执行该脚本最终会在 lib 下生成 index.js 文件:
lib ├── index.js # umd 总文件
webpack.conf.js 配置如下:
// build/webpack.conf.js // ...忽略 module.exports = { mode: 'production', // 指定入口文件src/index.js,该入口文件由`build:file`脚本自动生成 entry: { app: ['./src/index.js'] }, output: { // 在lib文件中生成 path: path.resolve(process.cwd(), './lib'), // 生成lib/index.js filename: 'index.js', // 生成umd模块 libraryTarget: 'umd', // src/index.js文件采用export default语法抛出,因此需要设置libraryExport // 否则引入的UI组件库需要使用.default才能引用到抛出的对象 // if your entry has a default export of `MyDefaultModule` // var MyDefaultModule = _entry_return_.default; // 这里踩过坑,所以说明一下,不配置的话遇到的问题是引入的UI组件库没法解构 libraryExport: 'default', }, resolve: { extensions: ['.js', '.vue', '.json'], // 'element-ui': path.resolve(__dirname, '../') // alias中的'element-ui'作为npm包抛出后指向了业务项目node_modules所在的npm包路径 alias: config.alias }, externals: { // 构建只排除vue // umd模块通过CDN形式引入,因此将所有的组件、utils、i18n等构建在内 // umd模块没有按需引入功能 vue: config.vue }, // ...忽略 };
构建文件 lib/index.js 主要的功能是用于CDN形式引入项目,并且无法做到按需加载,产生的体积非常大,对于简单的应用可能不适用。
webpack --config build/webpack.common.js
webpack --config build/webpack.common.js 脚本用于构建commonjs2总文件,执行该脚本最终会在 lib 下生成 element-ui.common.js 文件:
lib ├── element-ui.common.js # commonjs2 总文件
由于该文件需要在业务层面再次使用Webpack构建,因此考量的方面较多。在分析Webpack配置之前,再次回顾一下 Element 能为我们做什么: