Skip to content
本页目录

剖析 element-ui 中新建组件的命令

1. 命令

new:
	node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS))

2. 作用

快速生成一个新组件相关的文件,不用一个个去手动新建且修改内容。

3. 源码解析

3.1 判断组件名是否合法

javascript
"use strict";

console.log();
process.on("exit", () => {
    console.log();
});

if (!process.argv[2]) {
    console.error("[组件名]必填 - Please enter new component name");
    process.exit(1);
}

3.2 引入依赖

javascript
// 路径模块
const path = require("path");
// 读写文件需要
const fs = require("fs");
// 文件保存
const fileSave = require("file-save");
// 转驼峰工具
const uppercamelcase = require("uppercamelcase");

3.3 定义文件内容模板

javascript
// 定义一系列文件模板
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}`,
    },
    ...省略,
];

3.4 将组件添加到components.json中

javascript
// 添加到 components.json
const componentsFile = require('../../components.json');
// 判断是否此组件名已存在
if (componentsFile[componentname]) {
  console.error(`${componentname} 已存在.`);
  process.exit(1);
}
componentsFile[componentname] = `./packages/${componentname}/index.js`;
fileSave(path.join(__dirname, '../../components.json'))
  .write(JSON.stringify(componentsFile, null, '  '), 'utf8')
  .end('\n');

3.5 将scss文件添加到index.scss中

javascript
// 添加到 index.scss
const 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');

3.6 将组件ts类型文件 添加到 element-ui.d.ts

javascript
// 添加到 element-ui.d.ts
const 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');

3.7 将上面定义的模板写入到文件中

javascript
// 创建 package,将模版内容写入到对应文件中
Files.forEach(file => {
  fileSave(path.join(PackagePath, file.filename))
    .write(file.content, 'utf8')
    .end('\n');
});

3.8 将新增的组件添加到nav.config.json中

javascript
// 添加到 nav.config.json
const 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');