当前位置:   article > 正文

Element UI 组件库分析和二次开发(一)_element ui 二次开发

element ui 二次开发

我的本地开发环境:M1 芯片Mac,node v12.22.10。

一、Element UI 组件库二次开发的大致流程

1. 从 Element 官方 clone 一份 dev 源码到本地

2. 安装依赖:yarn 或者 npm i 

我用的是 npm i(用 yarn 安装依赖会失败报红色错误)。

npm i 的时候可能会出现 node-pre-gyp 的报错(但不是红色的),直接忽略,最终本地开发环境还是能成功启动。

已经安装过依赖、或者已经启动过的项目,第二次启动的时候遇到报错的解决办法:

删除 node_modules, package-lock.json,关闭整个终端重新启动,然后再 npm i,npm run dev。

3. 启动开发环境 npm run dev

每次 npm run dev 的时候都会去重新安装依赖,非常耗时,可以把 package.json dev script 里的 npm run bootstrap 删掉。

4. 修改组件源码

组件内容在 “packages/组件目录” 里修改。

组件样式在 “packages/theme-chalk/src/组件名.scss” 里修改。

查看效果可以在 “examples/docs/zh-CN/组件名.md” 里增加自己需要调试的代码,就可以在页面的相应的组件的例子中看到自己修改后的效果。

5. 新增组件可以用 make 命令

在项目根目录下命令行输入 make 可以查看全部可用的 make 命令。新增组件的命令是:

make new <component-name> [中文名]

这条命令会创建新组件 package. 例如 'make new button 按钮',新增组件时要添加新文件或修改的地方都会自动处理。

6. 如果要上传到 npm,需要更改包名(npm 上包名不能重复)

项目根目录名和 package.json 里的 “name” 值都要改。

7. 打包 npm run dist

打包完成后会重新在项目根目录生成 lib 目录。

提交二次开发后的代码到 git(注意:lib文件也一定要上传)。

8. 在其他项目中使用更新后的 Element UI

偷懒的一种方法是:复制打包生成的 lib 目录替换掉开发项目中 node_modules 下 element-ui 下的 lib 目录。(但不建议,不规范

规范的方法是:在开发项目的 package.json 文件的 dependencies 中新增 element-ui 这一项,指向二次开发组件库的 github 地址(这里一定注意需指定分支或者tag号,默认是master)。

  1. "dependencies": {
  2. "element-ui": "git+https://github.com/xxx/element.git#dev"
  3. },

执行 npm i,将二次开发的 Element 组件库安装到开发项目里。

9. 重启项目


  1. <!-- 引入样式 -->
  2. <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  3. <!-- 引入组件库 -->
  4. <script src="https://unpkg.com/element-ui/lib/index.js"></script>

从官网直接引用样式文件和js文件的示例可以知道,完整的样式文件在 lib/theme-chalk/index.css,完整的 js 文件在 lib/index.js。

二、Element 项目目录介绍

  1. |- build webpack相关的打包配置文件
  2. |- examples Element 官网
  3. |- assets 官网需要的一些静态资源,例如: 字体、样式、图片
  4. |- components 官网的公共组件, 例如: headr、foot
  5. |- docs/zh-CN 各个组件的文档
  6. |- pages 官网的页面
  7. |- packages 组件源码
  8. |- src
  9. |- index.js 所有组件注册的入口文件, 该文件由脚本`build/bin/build-entry.js`生成
  10. |- test 测试文件, 使用 karma 框架
  11. |- types 类型声明文件
  12. |- components.json 表明了组件的文件路径,方便webpack打包时获取组件的文件路径
  13. |- .gitattributes 允许我们指定由git使用的文件和路径的属性
  14. |- .npmignore 上传npm的配置文件
  15. |- FAQ.md 常见的组件库问题
  16. |- Makefile 是一个适用于c/c++的工具,make环境下,输入make命令将会执行makefile文件中的某个目标命令

三、 packages目录分析

packages 目录分为组件目录和 theme-chalk 主题样式目录。

theme-chalk 主题样式目录包含了所有组件的样式,用 sass 编写。其中 src/common/var.scss 文件包含了所有颜色、边框以及单个组件抽取出来的的样式变量。如果要修改涉及到全局变量,那么就在 var.scss 中定义。

四、 package.json

  1. name:项目名称,不能重复
  2. version:版本号
  3. main:项目主要入口点
  4. files:被项目包含的文件名数组(除非是被规则忽略的文件)
  5. scripts:项目脚本命令
  6. repository:指明代码仓库
  7. homepage:项目主页url
  8. keywords:项目关键词,有助于其他人发现包
  9. license:指定license来让用户知道他们的使用权力和任务限制
  10. bugs:项目的issue地址
  11. dependencies:指定了生产环境的依赖的包名和其版本范围的映射,不要将测试或过渡性的依赖放入其中
  12. peerDependencies:当主机无法导入依赖包时,指明哪些库与这个依赖包兼容
  13. devDependencies:指定了开发环境的依赖的包名和其版本范围的映射

五、 scripts脚本命令解析

  • bootstrap 安装依赖包
  • build:file 构建官网所需的文件
  • build:theme 构建主题样式
  • build:utils 用 babel 编译工具函数库
  • build:umd 编译生成 umd 模块的语言包
  • clean 清理打包后的文件
  • deploy:build 生产环境下构建官网
  • deploy:extension 在生产环境下构建主题插件
  • dev:extension 启动主题插件的开发环境,可以进行开发调试
  • dev 启动本地开发环境,进行能够调试开发
  • dev:play 用于查看某个组件的效果
  • dist 打包组件库
  • lint 校验文件
  • pub 检测分支是否冲突
  • test 测试项目

1、bootstrap

"bootstrap": "yarn || npm i"

安装依赖包。

2、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/iconInit.js

将 packages/theme-chalk/src/icon.scss 文件中的 icon 抽离出来放入 examples/icon.json 文件。

如将 platform-eleme 放入 icon.json 的数组中:

packages/theme-chalk/src/icon.scss

  1. .el-icon-platform-eleme:before {
  2. content: "\e7ca";
  3. }

icon.json

"platform-eleme"

生成 icon.json 文件,在 entry.js 中引入,并且绑定在 vue 原型上。

  1. import icon from './icon.json';
  2. Vue.prototype.$icon = icon; // Icon 列表页用

应用在文档中 examples/docs/zh-CN/icon.md,通过之后说到的 md-loader 解析成 vue 组件,渲染在官网上。

node build/bin/build-entry.js

执行后自动生成项目的入口文件 src/index.js,用 json-templater 结合变量生成模板,避免每次新增组件时手动在 src/index.js 中引入并导出组件。新增组件时,只要在 components.json 里维护好组件路径就可以了。

node build/bin/i18n.js

根据模板创建各个语言下的组件,只需要维护 examples/i18n/page.json 文件,执行命令自动生成官网上的语言组件。

node build/bin/version.js

添加 /package.json 里的 version 作为新版本号,自动生成 examples/version.json,用于记录组件库的版本信息,这些版本会渲染在官网组件页面的头部导航栏。

examples/components/header.vue

  1. created() {
  2. const xhr = new XMLHttpRequest();
  3. xhr.onreadystatechange = _ => {
  4. if (xhr.readyState === 4 && xhr.status === 200) {
  5. const versions = JSON.parse(xhr.responseText);
  6. this.versions = Object.keys(versions).reduce((prev, next) => {
  7. prev[next] = versions[next];
  8. return prev;
  9. }, {});
  10. }
  11. };
  12. xhr.open('GET', '/versions.json');
  13. xhr.send();
  14. let primaryLast = '#409EFF';
  15. bus.$on(ACTION_USER_CONFIG_UPDATE, (val) => {
  16. let primaryColor = val.global['$--color-primary'];
  17. if (!primaryColor) primaryColor = '#409EFF';
  18. const base64svg = 'data:image/svg+xml;base64,';
  19. const imgSet = document.querySelectorAll('h1 img');
  20. imgSet.forEach((img) => {
  21. img.src = `${base64svg}${window.btoa(window.atob(img.src.replace(base64svg, '')).replace(primaryLast, primaryColor))}`;
  22. });
  23. primaryLast = primaryColor;
  24. });
  25. }

构建新版本的时候要更改2个地方:

  1. package.json 里的 version
  2. build/bin/version.js 这段代码里写死的“2.15”改成 package.json 文件里 version 的“主版本号.次版本号”
if (!content[version]) content[version] = '2.15';

3、build:theme

"build:theme": "node build/bin/gen-cssfile && gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib lib/theme-chalk"

主要是处理样式相关的脚本。拆开来分析下:

node build/bin/gen-cssfile

执行该文件通过组件列表(components.json)生成组件样式入口文件 packages/theme-chalk/src/index.scss,并将所有组件的样式都导入。

gulp build --gulpfile packages/theme-chalk/gulpfile.js

把所有组件的 scss 文件(packages/theme-chalk/src/*.scss)通过 gulp 编译成 css,并放置到 packages/theme-chalk/lib 目录下

打包和压缩的工作平时一般交给 webpack 来做,但是基于工作流用 gulp 更加快捷和方便。

为什么需要编译呢?

因为 element 在使用时有两种引入方式:

  • 全局引用:
  1. import Vue from 'vue';
  2. import ElementUI from 'element-ui';
  3. import 'element-ui/lib/theme-chalk/index.css';
  4. import App from './App.vue';
  5. Vue.use(ElementUI);
  6. new Vue({
  7. el: '#app',
  8. render: h => h(App)
  9. });

引入了 lib\theme-chalk\index.css 文件

  • 局部引入:
  1. import Vue from 'vue';
  2. import { Button, Select } from 'element-ui';
  3. import App from './App.vue';
  4. Vue.component(Button.name, Button);
  5. Vue.component(Select.name, Select);
  6. /* 或写为
  7. * Vue.use(Button)
  8. * Vue.use(Select)
  9. */
  10. new Vue({
  11. el: '#app',
  12. render: h => h(App)
  13. });

不需要引入 css 文件,只需引入对应的 scss 文件。 这就是为什么需要编译 scss 的原因。

cp-cli packages/theme-chalk/lib lib/theme-chalk

cp-cli 是一个跨平台的 copy 工具,将gulp build --gulpfile .\packages\theme-chalk\gulpfile.js编译生成的 css 目录(packages/theme-chalk/lib)复制到 lib/theme-chalk 下,方便全局引入 css:

import 'element-ui/lib/theme-chalk/index.css';

4、build:utils

"build:utils": "cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js"

将 src 目录下的内容忽略 index.js 通过 babel 转译后移动到 lib 下。

5、build:umd

"build:umd": "node build/bin/build-locale.js"

执行后生成 umd 模块的语言包。

将 src/locale/lang 下的语言包都编译到 lib/umd/locale 下。

6、clean

"clean": "rimraf lib && rimraf packages/*/lib && rimraf test/**/coverage"

清除打包后的文件。

7、deploy:build

"deploy:build": "npm run build:file && cross-env NODE_ENV=production webpack --config build/webpack.demo.js && echo element.eleme.io>>examples/element-ui/CNAME"

npm run build:file 前文分析过了,主要构建官网文件。接下来分析新的构建脚本。

生产环境下构建官网:

cross-env NODE_ENV=production webpack --config build/webpack.demo.js

8、deploy:extension

"deploy:extension": "cross-env NODE_ENV=production webpack --config build/webpack.extension.js"

在生产环境下构建主题插件,主题编辑器的 chorme 插件项目的 webpack 配置,项目在 extension 目录下。执行命令后会在 extension 目录下生成 dist 目录,其中包含了 chorme 插件,在浏览器加载已解压的扩展程序就可以使用主题生成插件。

9、dev:extension

"dev:extension": "rimraf examples/extension/dist && cross-env NODE_ENV=development webpack --watch --config build/webpack.extension.js"

启动主题插件的开发环境,可以进行开发调试。

10、dev

"dev": "npm run bootstrap && npm run build:file && cross-env NODE_ENV=development webpack-dev-server --config build/webpack.demo.js & node build/bin/template.js"

首先用 npm run bootstrap 安装依赖。npm run build:file 在前面也有提到,主要用来自动化生成一些文件。主要是 node build/bin/build-entry.js,用于生成 Element 的入口 js:先是读取根目录的 components.json,这个 json 文件维护着 Element 所有的组件路径映射关系,键为组件名,值为组件源码的入口文件;然后遍历键值,将所有组件进行 import,对外暴露 install 方法,把所有 import 的组件通过 Vue.component(name, component) 方式注册为全局组件,并且把一些弹窗类的组件挂载到 Vue 的原型链上。

在生成了入口文件的 src/index.js 之后就会运行 webpack-dev-server

启动组件库本地开发环境。在更改后可以热更新官网。 

11、dev:play

"dev:play": "npm run build:file && cross-env NODE_ENV=development PLAY_ENV=true webpack-dev-server --config build/webpack.demo.js"

组件测试项目,在 examples/play/index.vue 中可以引入组件库任意组件,也可以直接使用 dev 启动的项目,在文档中使用组件。

用于查看某个组件的效果。适用于组件按需加载的显示效果。在 webpack.demo.js 通过环境变量配置输入。

build/webpack.demo.js

  1. const isPlay = !!process.env.PLAY_ENV;
  2. // ……省略webpack具体配置
  3. entry: isProd ? {
  4. docs: './examples/entry.js'
  5. } : (isPlay ? './examples/play.js' : './examples/entry.js'),

examples/play.js

  1. import Vue from 'vue';
  2. import Element from 'main/index.js';
  3. import App from './play/index.vue';
  4. import 'packages/theme-chalk/src/index.scss';
  5. Vue.use(Element);
  6. new Vue({ // eslint-disable-line
  7. render: h => h(App)
  8. }).$mount('#app');

12、dist

"dist": "npm run clean && npm run build:file && npm run lint && webpack --config build/webpack.conf.js && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run build:utils && npm run build:umd && npm run build:theme"

打包组件库。

npm run clean && npm run build:file && npm run lint 都已经解释过了,分别是清除上一次打包产物、生成入口文件以及 i18n 文件和 eslint 检测。

webpack --config build/webpack.conf.js

生成 umd 格式的 js 文件(index.js

  1. const path = require('path');
  2. const ProgressBarPlugin = require('progress-bar-webpack-plugin');
  3. const VueLoaderPlugin = require('vue-loader/lib/plugin');
  4. const TerserPlugin = require('terser-webpack-plugin');
  5. const config = require('./config');
  6. console.log(config)
  7. module.exports = {
  8. // 模式
  9. mode: 'production',
  10. // 入口
  11. entry: {
  12. app: ['./src/index.js']
  13. },
  14. // 输出
  15. output: {
  16. path: path.resolve(process.cwd(), './lib'),
  17. publicPath: '/dist/',
  18. // 输出的文件名
  19. filename: 'index.js',
  20. // 初始的chunk文件名称
  21. chunkFilename: '[id].js',
  22. // library 暴露为 AMD 模块。 在 AMD 或 CommonJS 的 require 之后可访问(libraryTarget:'umd')
  23. libraryTarget: 'umd',
  24. // 入口的默认导出将分配给 library target:
  25. // if your entry has a default export of `MyDefaultModule`
  26. // var MyDefaultModule = _entry_return_.default;
  27. libraryExport: 'default',
  28. // 输出一个库,为你的入口做导出。
  29. library: 'ELEMENT',
  30. // 会把 AMD 模块命名为 UMD 构建
  31. umdNamedDefine: true,
  32. // 为了使 UMD 构建在浏览器和 Node.js 上均可用,应将 output.globalObject 选项设置为 'this'。对于类似 web 的目标,默认为 self。
  33. globalObject: 'typeof self !== \'undefined\' ? self : this'
  34. },
  35. // 解析
  36. resolve: {
  37. // 能够使用户在引入模块时不带扩展.尝试按顺序解析这些后缀名。如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
  38. extensions: ['.js', '.vue', '.json'],
  39. // 创建 import 或 require 的别名,来确保模块引入变得更简单。
  40. alias: config.alias
  41. },
  42. // 外部扩展
  43. externals: {
  44. vue: config.vue
  45. },
  46. // 优化
  47. optimization: {
  48. // 允许你通过提供一个或多个定制过的 TerserPlugin 实例, 覆盖默认压缩工具(minimizer)
  49. minimizer: [
  50. new TerserPlugin({
  51. terserOptions: {
  52. output: {
  53. comments: false
  54. }
  55. }
  56. })
  57. ]
  58. },
  59. // 性能
  60. performance: {
  61. // 不展示警告或错误提示。
  62. // 官网推荐使用error,有助于防止把体积大的bundle部署到生产环境,从而影响网页的性能
  63. // 很奇怪这里要把它关闭
  64. hints: false
  65. },
  66. // stats对象
  67. stats: {
  68. // 告知 stats 是否添加关于子模块的信息。
  69. children: false
  70. },
  71. // 模块
  72. module: {
  73. // 使用babel-loader和vue-loader
  74. rules: [
  75. {
  76. test: /\.(jsx?|babel|es6)$/,
  77. include: process.cwd(),
  78. exclude: config.jsexclude,
  79. loader: 'babel-loader'
  80. },
  81. {
  82. test: /\.vue$/,
  83. loader: 'vue-loader',
  84. options: {
  85. compilerOptions: {
  86. preserveWhitespace: false
  87. }
  88. }
  89. }
  90. ]
  91. },
  92. // 插件
  93. plugins: [
  94. new ProgressBarPlugin(),
  95. new VueLoaderPlugin()
  96. ]
  97. };

webpack --config build/webpack.common.js

生成 commonjs 格式的 js 文件(element-ui.common.js),require 时默认加载的是这个文件。

    libraryTarget: 'commonjs2'

与 webpack.conf.js 不同在于输出 output 的 libraryExport

前者暴露的是 commonjs2,后者暴露的是 umd

webpack --config build/webpack.component.js

与前两者的 index.js 入口不同,以 components.json 为入口,将每一个组件打包生成一个文件,用于按需加载。

npm run build:utils && npm run build:umd && npm run build:theme 也已经讲过,分别是转译工具方法、转译语言包、生成样式文件。

13、lint

"lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet"

eslint 校验 src、packages 和 build 目录下的文件。

14、pub

"pub": "npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js && sh build/deploy-faas.sh"

npm run bootstrap 下载依赖。

sh build/git-release.sh:主要是检测 dev 分支是否冲突。

  1. #!/usr/bin/env sh
  2. # 切换到dev分支
  3. git checkout dev
  4. # 检测本地是否有未提交文件
  5. if test -n "$(git status --porcelain)"; then
  6. # 输出日志
  7. echo 'Unclean working tree. Commit or stash changes first.' >&2;
  8. exit 128;
  9. fi
  10. # 检测本地分支是否有误
  11. if ! git fetch --quiet 2>/dev/null; then
  12. # 输出日志
  13. echo 'There was a problem fetching your branch. Run `git fetch` to see more...' >&2;
  14. exit 128;
  15. fi
  16. # 检测是否有最新提交
  17. if test "0" != "$(git rev-list --count --left-only @'{u}'...HEAD)"; then
  18. # 输出日志
  19. echo 'Remote history differ. Please pull changes.' >&2;
  20. exit 128;
  21. fi
  22. # 输出日志
  23. echo 'No conflicts.' >&2;

sh build/release.sh 脚本完成了以下工作:

  1. 合并 dev 分支到 master
  2. 修改样式包和组件库的版本号
  3. 发布样式包和组件库
  4. 提交 master 和 dev 分支到远程仓库

该脚本在发布组件库时可以使用,特别是其中自动更改版本号的功能(每次 publish 时都忘改版本号)。这里提交代码到远程仓库的日志很简单。

  1. #!/usr/bin/env sh
  2. set -e
  3. # 切换到master
  4. git checkout master
  5. # 合并dev分支
  6. git merge dev
  7. # npx: 使用本地已安装的可执行工具,而不需要配置 scripts
  8. VERSION=`npx select-version-cli`
  9. # 更新版本号
  10. read -p "Releasing $VERSION - are you sure? (y/n)" -n 1 -r
  11. echo # (optional) move to a new line
  12. if [[ $REPLY =~ ^[Yy]$ ]]
  13. then
  14. # 输出:压缩版本
  15. echo "Releasing $VERSION ..."
  16. # build
  17. # 编译打包
  18. VERSION=$VERSION npm run dist
  19. # ssr test
  20. node test/ssr/require.test.js
  21. # 发布到npm
  22. # publish theme
  23. # 输出:压缩theme-chalk版本
  24. echo "Releasing theme-chalk $VERSION ..."
  25. cd packages/theme-chalk
  26. # 更改主题包的版本信息
  27. npm version $VERSION --message "[release] $VERSION"
  28. # 如果是beta版本则打个beta标签
  29. if [[ $VERSION =~ "beta" ]]
  30. then
  31. npm publish --tag beta
  32. else
  33. npm publish
  34. fi
  35. cd ../..
  36. # commit
  37. git add -A
  38. git commit -m "[build] $VERSION"
  39. # 更改组件库的版本信息
  40. npm version $VERSION --message "[release] $VERSION"
  41. # publish
  42. # 发布到远程仓库
  43. git push eleme master
  44. git push eleme refs/tags/v$VERSION
  45. git checkout dev
  46. git rebase master
  47. git push eleme dev
  48. # 发布组件库
  49. if [[ $VERSION =~ "beta" ]]
  50. then
  51. npm publish --tag beta
  52. else
  53. npm publish
  54. fi
  55. fi

node build/bin/gen-indices.js 生成目录,支持搜索:

  1. 'use strict';
  2. // 生成目录
  3. const fs = require('fs');
  4. const path = require('path');
  5. // 是一个托管的全文、数字和分面搜索引擎,能够从第一次击键交付实时结果。
  6. const algoliasearch = require('algoliasearch');
  7. // 将Unicode str转换为段字符串,确保在URL或文件名中使用它是安全的。
  8. // https://www.npmjs.com/package/transliteration?activeTab=readme
  9. // demo:
  10. // slugify('你好,世界');
  11. // // ni-hao-shi-jie
  12. const slugify = require('transliteration').slugify;
  13. // 密钥
  14. const key = require('./algolia-key');
  15. const client = algoliasearch('4C63BTGP6S', key);
  16. const langs = {
  17. 'zh-CN': 'element-zh',
  18. 'en-US': 'element-en',
  19. 'es': 'element-es',
  20. 'fr-FR': 'element-fr'
  21. };
  22. // 四种语言
  23. ['zh-CN', 'en-US', 'es', 'fr-FR'].forEach(lang => {
  24. const indexName = langs[lang];
  25. const index = client.initIndex(indexName);
  26. index.clearIndex(err => {
  27. if (err) return;
  28. // 读取/examples/docs/中的文件
  29. fs.readdir(path.resolve(__dirname, `../../examples/docs/${ lang }`), (err, files) => {
  30. if (err) return;
  31. let indices = [];
  32. files.forEach(file => {
  33. console.log(file)
  34. const component = file.replace('.md', '');
  35. const content = fs.readFileSync(path.resolve(__dirname, `../../examples/docs/${ lang }/${ file }`), 'utf8');
  36. const matches = content
  37. .replace(/:::[\s\S]*?:::/g, '')
  38. .replace(/```[\s\S]*?```/g, '')
  39. .match(/#{2,4}[^#]*/g)
  40. .map(match => match.replace(/\n+/g, '\n').split('\n').filter(part => !!part))
  41. .map(match => {
  42. const length = match.length;
  43. if (length > 2) {
  44. const desc = match.slice(1, length).join('');
  45. return [match[0], desc];
  46. }
  47. return match;
  48. });
  49. indices = indices.concat(matches.map(match => {
  50. const isComponent = match[0].indexOf('###') < 0;
  51. const title = match[0].replace(/#{2,4}/, '').trim();
  52. const index = { component, title };
  53. index.ranking = isComponent ? 2 : 1;
  54. index.anchor = slugify(title);
  55. index.content = (match[1] || title).replace(/<[^>]+>/g, '');
  56. return index;
  57. }));
  58. });
  59. index.addObjects(indices, (err, res) => {
  60. console.log(err, res);
  61. });
  62. });
  63. });
  64. });

15、test

"test": "npm run lint && npm run build:theme && cross-env CI_ENV=/dev/ BABEL_ENV=test karma start test/unit/karma.conf.js --single-run" "test:watch": "npm run build:theme && cross-env BABEL_ENV=test karma start test/unit/karma.conf.js"

单元测试:UI 组件作为高度抽象的基础公共组件,编写单元测试是很有必要的。

其他

1. 新增组件的 scss 样式文件放在 packages/theme-chalk/src 目录下,css 样式文件要放在 packages/theme-default/src 目录下。

参考文章

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/300017
推荐阅读