Read the element UI source code and how to find the style and component entry file

How to read?

  1. First, find the entry file
  2. Find style and component files
  3. Are there any reusable small components, and what are the large components composed of these small components

Entry file

Project startup document:

"scripts": {
    "bootstrap": "yarn || npm i",
    "build:file": "node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js",
    "build:theme": "node build/bin/gen-cssfile && gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib lib/theme-chalk",
    "build:utils": "cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js",
    "build:umd": "node build/bin/build-locale.js",
    "clean": "rimraf lib && rimraf packages/*/lib && rimraf test/**/coverage",
    "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",
    "deploy:extension": "cross-env NODE_ENV=production webpack --config build/webpack.extension.js",
    "dev:extension": "rimraf examples/extension/dist && cross-env NODE_ENV=development webpack --watch --config build/webpack.extension.js",
    "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",
    "dev:play": "npm run build:file && cross-env NODE_ENV=development PLAY_ENV=true webpack-dev-server --config build/webpack.demo.js",
    "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",
    "i18n": "node build/bin/i18n.js",
    "lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet",
    "pub": "npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js",
    "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"
  }

It can be seen from the file that the startup file has the following steps:

  • node build/bin/iconInit.js read packages / theme chat / SRC / icon SCSS file, get icon style

  • node build/bin/build-entry.js read components json file, which records the entry files of all components, saves them in json format, and defines three template arrays:
    var includeComponentTemplate = [];
    var installTemplate = [];
    var listTemplate = [];
    Then traverse the components JSON file, render all components as import {{name}} from '... / packages / {{package} / index js’; Save to includeComponentTemplate array;
    Exclude any one of ['Loading', 'MessageBox', 'Notification', 'Message', 'infinitycoll'] in the key, and save the remaining {name}} to the installTemplate array;
    Then save the component names that are not Loading to the listTemplate array;
    After that, the arrays are spliced through join (constant of the end of line character of the operating system) and rendered to MAIN_TEMPLATE, which is the template for component registration:
    var MAIN_TEMPLATE = `/* Automatically generated by './build/bin/build-entry.js' */

    {{include}}
    import locale from 'element-ui/src/locale';
    import CollapseTransition from 'element-ui/src/transitions/collapse-transition';
    
    const components = [
    {{install}},
      CollapseTransition
    ];
    
    const install = function(Vue, opts = {}) {
      locale.use(opts.locale);
      locale.i18n(opts.i18n);
    
      components.forEach(component => {
        Vue.component(component.name, component);
      });
    
      Vue.use(InfiniteScroll);
      Vue.use(Loading.directive);
    
      Vue.prototype.$ELEMENT = {
        size: opts.size || '',
        zIndex: opts.zIndex || 2000
      };
    
      Vue.prototype.$loading = Loading.service;
      Vue.prototype.$msgbox = MessageBox;
      Vue.prototype.$alert = MessageBox.alert;
      Vue.prototype.$confirm = MessageBox.confirm;
      Vue.prototype.$prompt = MessageBox.prompt;
      Vue.prototype.$notify = Notification;
      Vue.prototype.$message = Message;
    
    };
    
    /* istanbul ignore if */
    if (typeof window !== 'undefined' && window.Vue) {
      install(window.Vue);
    }
    
    export default {
      version: '{{version}}',
      locale: locale.use,
      i18n: locale.i18n,
      install,
      CollapseTransition,
      Loading,
    {{list}}
    };
    `;
    

    How to register templates for rendering components:
    var template = render(MAIN_TEMPLATE, {
    include: includeComponentTemplate.join(endOfLine),
    install: installTemplate.join(',' + endOfLine),
    version: process.env.VERSION || require('.../.../package.json').version,
    list: listTemplate.join(',' + endOfLine)
    });
    Finally, write the rendered content to Src / index JS file.

webpack entry file

webpack.demo.js: the project is packaged according to isProd or isPlay environment. The packaging entry is/ examples/entry.js or/ examples/play.js, because const isPlay =!! process. env. PLAY_ ENV; , So, it's examples / entry js. The export file is: path resolve(process.cwd(), ‘./ Examples / element UI / '), in the examples / element UI directory under the current working directory.

Project entry file examples / entry js

This file is equivalent to the main. Of an ordinary vue file js,

With routing:

import VueRouter from 'vue-router';
import routes from './route.config';

There are vue instances and entry templates:

import Vue from 'vue';
import entry from './app';

There are common components:

import Element from 'main/index.js';
import demoBlock from './components/demo-block';
import MainFooter from './components/footer';
import MainHeader from './components/header';
import SideNav from './components/side-nav';
import FooterNav from './components/footer-nav';
import title from './i18n/title';

Vue.use(Element);
Vue.use(VueRouter);
Vue.component('demo-block', demoBlock);
Vue.component('main-footer', MainFooter);
Vue.component('main-header', MainHeader);
Vue.component('side-nav', SideNav);
Vue.component('footer-nav', FooterNav);

There are common styles:

import 'packages/theme-chalk/src/index.scss';
import './demo-styles/index.scss'; // The basic styles of components, including @ import
import './assets/styles/common.css';
import './assets/styles/fonts/style.css';
import icon from './icon.json';

Finally, all elements and instances are hit on the #appDOM node:

new Vue({ // eslint-disable-line
  ...entry,
  router
}).$mount('#app');

How does the project find components and render them?

Rendering official documents through templates

In webpack demo. JS, where to find the home page template:

new HtmlWebpackPlugin({
      template: './examples/index.tpl',
      filename: './index.html',
      favicon: './examples/favicon.ico'
    }),

So where did you find the component template? In fact, the webpack entry file has told us:

"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"

It's build / bin / template JS file.

const templates = path.resolve(process.cwd(), './examples/pages/template');
const chokidar = require('chokidar');
let watcher = chokidar.watch([templates]);

watcher.on('ready', function() {
  watcher
    .on('change', function() {
      exec('npm run i18n');
    });
});

The chokidar library is used to monitor the files under examples/pages/template. Once the following files are found to have changed, the npm run i18n command is executed, while in package JSON, you can see:

"i18n": "node build/bin/i18n.js"

From build bin. i18n. JS, learned that:

Read is examples/i18n/page.json ,The document describes the functional directories; Then judge examples/pages Whether there are these directory files under the. If not, create them and use them examples/pages/template/Render the template file under and output to examples/pages Directory.

Through routing

Via route config. JS can see NAV config. JSON file, which records the directory of element project documents.

You can see the main execution logic of the document:

LOAD_MAP: Created a component whose closure can read the response language (the component can only be generated after running)
load: return LOAD_MAP
LOAD_DOCS_MAP: read/docs Documents in various languages under
loadDocs: return LOAD_DOCS_MAP
registerRoute: function read nav.config.json,And generate router Object return
 implement registerRoute
generateMiscRoutes: function Generate routing array
 implement generateMiscRoutes
 Made one v-model Template
...

This file is mainly for these functions, and the important logic of using components is registerRoute

Keywords: Front-end Vue elementUI

Added by Megahertza on Thu, 20 Jan 2022 17:32:05 +0200