【源码共读】| element 初始化组件功能

143 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。

【若川视野 x 源码共读】第15期 | element 初始化组件功能 点击了解本期详情一起参与

今天阅读的是:element new 初始化组件

github.com/lxchuan12/e…


尝试使用

首先,我们查看目录结构

image-20221202090716541

这个项目使用yarn安装依赖的,然后我们跳转至ReadMe.md => CONTRIBUTING.zh-CN.md

image-20221202091701121

运行代码,可能会发生以下错误

image-20221202092618050

解决方法:

"script":{
    "dev": "SET NODE_OPTIONS=--openssl-legacy-provider 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"
}

我们尝试去创建自己的组件

make new juejin
// windows 
node build/bin/new.js juejin

image-20221202104405251


源码分析

前面是一些校验和将输入参数转驼峰的操作,这里我们略过,重点看Files变量

  • 生成index.js

{
    filename: 'index.js',
        content: `import ${ComponentName} from './src/main';

/* istanbul ignore next */
${ComponentName}.install = function(Vue) {
  Vue.component(${ComponentName}.name, ${ComponentName});
};

export default ${ComponentName};`
},
  • 生成main.vue
{
    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.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')

  • 创建package.json
Files.forEach((file) => {
    fileSave(path.join(PackagePath, file.filename))
        .write(file.content, 'utf8')
        .end('\n')
})

总结

​ 通过对源码的分析,我们可以知道使用make new ${componentName}命令,通过预制的模板在对应的路径上生成对应的文件,利用file-save这个库来方便的生成对应的文件