Version Description
$ vue --version @vue/cli 4.5.9 $ node --version v14.0.0 $ npm --version 7.6.1
Source location - mac
/usr/local/lib/node_modules/@vue/cli
Process description
- According to package Bin in JSON can know that the entry file is in bin / Vue js
- vue. The command setting of create <app-name> is found in JS, and lib/create is invoked in the action hook.
create.js
- Get project absolute path
- Determine whether the project folder exists
- create folder
- Call lib / creator js
Creator.js
Creator.create()
-
Configure the preset plug-in group according to the selection when creating the project
-
Deep copy preset
-
Configure the configuration items of the default plug-in in preset: @ Vue / cli service, @ Vue / cli plugin router, @ Vue / cli plugin typescript, @ Vue / cli plugin vuex
-
Get package manager: yarn/npm/pnpm
-
Start creating the project and get the Vue cli version
-
Generate package according to the plug-in configuration in preset JSON file
-
Generate for pnpm npmrc file, generated for yarn yarnrc
-
Add git configuration for the project: git init
-
Installing the CLI plug-in: generates a file directory in the specified format
await generator.generate({ extractConfigFiles: preset.useConfigFiles, });
-
Wake up plug-in
-
Install and configure additional dependencies
-
running completion hooks
-
Generate readme md
-
Configure the state of GIT and configure git for the test
-
complete
Custom modify scaffold program
The plug-ins and other configurations used in the company's projects are basically similar, and there are many ways to improve development efficiency in the project development process, which can be customized in the scaffold program flow
- Get rid of the duplicate work of copy and paste, and avoid the bug that can not be debug ged caused by the loss of copy and paste
- Improve project development efficiency and unify project development style
Generate Vue config. JS - generate readme md
- generateVueConfig.js
// Generate readme md: lib/util/generateReademe.js // Generate Vue config. js: lib/util/generateVueConfig.js, I have other configuration items, which need to generate Vue according to the configuration config. js module.exports = function generateVueConfig(plugins) { const iconSvg = plugins['svg-sprite-loader'] ? `chainWebpack: config => { // svg rule loader const svgRule = config.module.rule('svg') // Find SVG loader svgRule.uses.clear() // Clear the existing loader. If not, it will be added after this loader svgRule.exclude.add(/node_modules/) // Regular match exclusion node_modules directory svgRule // Add svg new loader handling .test(/\.svg$/) .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]', }) // Modify images loader and add svg processing const imagesRule = config.module.rule('images') imagesRule.exclude.add(resolve('src/icon/svg')) config.module .rule('images') .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/) }` : '' return `const path = require('path') function resolve(dir) { return path.join(__dirname, './', dir) } module.exports = { publicPath: './', devServer: { proxy: { '/api': { target: 'http://localhost:5000', changeOrigin: true } } }, productionSourceMap: false, ${iconSvg} }` }
-
Modify the create process - creator js
// Custom build Vue config. js, write the configuration used many times, such as cross domain configuration. You can write it directly or write the content in another js file and import it if (!generator.files['vue.config.js']) { log() log('⚙\u{fe0f} Generating vue.config.js...') await writeFileTree(context, { 'vue.config.js': generateVueConfig(preset.otherPlugins), }) }
Configure and import custom npm package - imitation configuration @ Vue / cli XXX package
During development, some packages will always be introduced, such as axios, encrypted packages, UI framework packages, etc. they can be added during the early selection of vue create to generate code.
Process of importing @ Vue / cli XXX package:
- create.js, enter the overall process according to the new Creator. When initializing the Creator, the initial package list is passed in. Only the important codes are summarized below
// create.js const { getPromptModules } = require('./util/createTools') const creator = new Creator(name, targetDir, getPromptModules()) // getPromptModules() exports.getPromptModules = () => { return [ 'vueVersion', 'babel', 'typescript', 'pwa', 'router', 'vuex', 'cssPreprocessors', 'linter', 'unit', 'e2e' ].map(file => require(`../promptModules/${file}`)) }
- When initializing Creator, the promptmodule API is called, the related package is introduced, and the configuration command lib/promptModules/xxx of the related package is called
// Creator.js constructor(name, context, promptModules) { const promptAPI = new PromptModuleAPI(this); promptModules.forEach((m) => m(promptAPI)); // After the above commands are executed, the configuration commands of each related package will be displayed in the shell interface. At this time, the user can select or enter }
- In creator In the create () method, configuration items are configured for each package according to preset and stored in preset In plugins
// Creator. JS create () method, the following is only an example preset.plugins["@vue/cli-service"] = Object.assign( { projectName: name, }, preset ); if (cliOptions.bare) { preset.plugins["@vue/cli-service"].bare = true; } // legacy support for router if (preset.router) { preset.plugins["@vue/cli-plugin-router"] = {}; if (preset.routerHistoryMode) { preset.plugins["@vue/cli-plugin-router"].historyMode = true; } }
Copy the above process to import the packages you want to import during initialization, such as axios. In order to avoid conflicts, all the codes are developed separately. The following examples are axios and optional UI framework
- createOtherTools.js - copy the getPromptModules function, configure the custom package list, and add it to the initialization Creator
// lib/util/createOtherTools. The JS othermodules folder stores the command line associated with the custom package exports.getOtherPromptModules = () => { return [ 'axios', 'uiStruct' ].map(file => require(`../otherModules/${file}`)) } // create.js const { getPromptModules } = require('./util/createTools') const { getOtherPromptModules } = require('./util/createOtherTools') const creator = new Creator(name, targetDir, getPromptModules(), getOtherPromptModules())
- Import the command line configuration of related packages and store the configuration of custom packages in options In otherplugins
// Creator.js constructor(name, context, promptModules, otherPromptModules) { const promptAPI = new PromptModuleAPI(this); promptModules.forEach((m) => m(promptAPI)); otherPromptModules.forEach((m) => m(promptAPI)); // After the above commands are executed, the configuration commands of each related package will be displayed in the shell interface. At this time, the user can select or enter } // New otherModules folder // otherModules/axios.js module.exports = cli => { cli.injectFeature({ name: 'Axios', // The name displayed in the selection after the vue create command value: 'axios', // Corresponding value description: 'Promise based HTTP client for the browser and node.js', // introduce link: 'https://github.com/mzabriskie/axios', / / related links checked: true // It is displayed in the options after vue create command. Is it selected by default }) cli.onPromptComplete((answers, options) => { if (answers.features.includes('axios')) { // Whether the includes(value) contains the value defined above options.otherPlugins['axios'] = {} // Specify the corresponding enrollment here } }) } // otherModules/uiStruct.js module.exports = cli => { cli.injectFeature({ name: 'Choose UI Struct', // The name displayed in the selection after the vue create command value: 'ui-struct', // Corresponding value description: 'Choose a struct of UI that you want to use with the project' // introduce }) cli.injectPrompt({ name: 'uiStruct', when: answers => answers.features.includes('ui-struct'), // Judge whether to select message: 'Choose a struct of UI that you want to use with the project', // describe type: 'list', // Select a shell like command choices: [ { name: 'ant-design-vue', // Option name value: 'ant-design-vue' // Package name corresponding to option }, { name: 'element-ui', value: 'element-ui' } ], default: 'element-ui' // Default options }) cli.onPromptComplete((answers, options) => { if (answers.uiStruct) { options.otherPlugins[answers.uiStruct] = {} // answers.uiStruct stores the package name } }) }
- Add the introduction of customized package into the process and generate package Introduced before JSON
// Creator.js - create() function if (preset.otherPlugins) { Object.keys(preset.otherPlugins).forEach((dep) => { let { version } = preset.otherPlugins[dep]; pkg.dependencies[dep] = version ? version : "latest"; }); }