1. 前言
1.1 环境
- 操作系统: macOS 11.5.2
- 浏览器: Chrome 94.0.4606.81
-
1.2 阅读该文章可以get以下知识点
-
2. 开始
2.1 如何创建新组件
make new xxx
运行上面的命令会创建响应的资源文件
packages/xxx
- test/unit/specs/xxx.spec.js
- types/element-ui.d.ts
2.2 Makefile
```makefile .PHONY: dist test default: help
install: npm install
new:
这里会执行 build/bin/new.js下面的文件
node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS))
help:
@echo “ \033[35mmake\033[0m \033[1m命令使用说明\033[0m”
@echo “ \033[35mmake install\033[0m\t\033[0m\t\033[0m\t\033[0m\t—- 安装依赖”
@echo “ \033[35mmake new
挺有意思的写法,直接通过make new再去执行脚本<br />$(filter-out $@,$(MAKECMDGOALS))这段代码是将参数传入到new.js脚本中1. $@1. 会返回自身,例如 这里的new:,会返回new2. $(MAKECMDGOALS)1. 返回所有的参数,例如 make new xxx,会返回 new xx3. filter-out反过滤函数1. 有两个参数,第一个参数是匹配的字符串,第二个参数是需要处理的字符串2. 过滤掉所有匹配的字符串,保留不匹配的,例如; make new xxx, 返回xxx,过滤掉了new<a name="ezz5E"></a>## 2.3 new.js```javascript'use strict';console.log();process.on('exit', () => {console.log();});// 默认0和1是node环境变量和当前运行文件,第三个就是组件名if (!process.argv[2]) {console.error('[组件名]必填 - Please enter new component name');process.exit(1);}const path = require('path');const fs = require('fs');// 文件存储const fileSave = require('file-save');// 驼峰转化const uppercamelcase = require('uppercamelcase');// 组件吗const componentname = process.argv[2];// 如果有中文名,传入第四个参数,没有的话,直接去组件吗const chineseName = process.argv[3] || componentname;// 转化成大驼峰const ComponentName = uppercamelcase(componentname);// 获取packages的路径const PackagePath = path.resolve(__dirname, '../../packages', componentname);// 文件名和模板语法const Files = [{filename: 'index.js',content: `import ${ComponentName} from './src/main';/* istanbul ignore next */${ComponentName}.install = function(Vue) {Vue.component(${ComponentName}.name, ${ComponentName});};export default ${ComponentName};`},{filename: 'src/main.vue',content: `<template><div class="el-${componentname}"></div></template><script>export default {name: 'El${ComponentName}'};</script>`},{filename: path.join('../../examples/docs/zh-CN', `${componentname}.md`),content: `## ${ComponentName} ${chineseName}`},{filename: path.join('../../examples/docs/en-US', `${componentname}.md`),content: `## ${ComponentName}`},{filename: path.join('../../examples/docs/es', `${componentname}.md`),content: `## ${ComponentName}`},{filename: path.join('../../examples/docs/fr-FR', `${componentname}.md`),content: `## ${ComponentName}`},{filename: path.join('../../test/unit/specs', `${componentname}.spec.js`),content: `import { createTest, destroyVM } from '../util';import ${ComponentName} from 'packages/${componentname}';describe('${ComponentName}', () => {let vm;afterEach(() => {destroyVM(vm);});it('create', () => {vm = createTest(${ComponentName}, true);expect(vm.$el).to.exist;});});`},{filename: path.join('../../packages/theme-chalk/src', `${componentname}.scss`),content: `@import "mixins/mixins";@import "common/var";@include b(${componentname}) {}`},{filename: path.join('../../types', `${componentname}.d.ts`),content: `import { ElementUIComponent } from './component'/** ${ComponentName} Component */export declare class El${ComponentName} extends ElementUIComponent {}`}];// 添加到 components.jsonconst componentsFile = require('../../components.json');if (componentsFile[componentname]) {console.error(`${componentname} 已存在.`);process.exit(1);}componentsFile[componentname] = `./packages/${componentname}/index.js`;// 存储新的jsonfileSave(path.join(__dirname, '../../components.json')).write(JSON.stringify(componentsFile, null, ' '), 'utf8').end('\n');// 添加到 index.scssconst sassPath = path.join(__dirname, '../../packages/theme-chalk/src/index.scss');const sassImportText = `${fs.readFileSync(sassPath)}@import "./${componentname}.scss";`;fileSave(sassPath).write(sassImportText, 'utf8').end('\n');// 添加到 element-ui.d.tsconst elementTsPath = path.join(__dirname, '../../types/element-ui.d.ts');let elementTsText = `${fs.readFileSync(elementTsPath)}/** ${ComponentName} Component */export class ${ComponentName} extends El${ComponentName} {}`;const index = elementTsText.indexOf('export') - 1;const importString = `import { El${ComponentName} } from './${componentname}'`;elementTsText = elementTsText.slice(0, index) + importString + '\n' + elementTsText.slice(index);fileSave(elementTsPath).write(elementTsText, 'utf8').end('\n');// 创建 packageFiles.forEach(file => {fileSave(path.join(PackagePath, file.filename)).write(file.content, 'utf8').end('\n');});// 添加到 nav.config.jsonconst navConfigFile = require('../../examples/nav.config.json');Object.keys(navConfigFile).forEach(lang => {let groups = navConfigFile[lang][4].groups;groups[groups.length - 1].list.push({path: `/${componentname}`,title: lang === 'zh-CN' && componentname !== chineseName? `${ComponentName} ${chineseName}`: ComponentName});});fileSave(path.join(__dirname, '../../examples/nav.config.json')).write(JSON.stringify(navConfigFile, null, ' '), 'utf8').end('\n');console.log('DONE!');
3. 总结
- 熟悉了一些Makefile的语法
- 通过Makefile的方式,去执行一些脚本,代码很简洁,如 make new, make help,不需要去写package.json scripts,减少了script的脚本,但是也有一定的理解成本,有些前端同学不懂Makefile,windows环境需要gcc环境
-
4. 参考文档
- https://www.npmjs.com/package/element-ui
