Vue source code

Once we have vUE installed, how do we understand the code structure of VUE and where do we start?

1.1. Vue source code entry

The entry to vue is package.json

So what does that mean

  • Dependences:
"Dependencies ": {"vue": "^2.5.2"},Copy the code

This code tells us the vUE version: 2.5.2

  • engines
"Engines" : {" node ":" > = 6.0.0 ", "NPM" : "> = 3.0.0"},Copy the code

Specifies the current node version and NPM version

  • devDependencies

Inside is the introduction of various loaders

  • scripts
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js"
  },
Copy the code

That’s the point. We NPM run build, NPM run dev execute these commands. He tells us that we are executing that file when we execute build.

  1. Dev: read the configuration file is build/webpack dev. Conf. Js
  2. Build: The configuration file read is buld/build.js

1.2. Structure of project files

Let’s take a look at the overall directory structure of the project

1.2.1. Webpack configuration

1.2.1.1 webpack.dev.config.js is the local development environment reads the configuration file.

'use strict' // Define variables, Const utils = require('./utils') const webpack = require('webpack') const config = require('.. /config') const merge = require('webpack-merge') const path = require('path') // Introduce public configuration const baseWebpackConfig = // const CopyWebpackPlugin = require('copy-webpack-plugin') // require('./webpack.base Package the HTML into the DIST file, Const HtmlWebpackPlugin = require('html-webpack-plugin') // Const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const portfinder = require('portfinder') const HOST = process.env.HOST const PORT = process.env.port && Number(process.env.port) // Merge two configurations. Const devWebpackConfig = merge(baseWebpackConfig, {module: {rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, // cheap-module-eval-source-map is faster for development devtool: config.dev.devtool, // these devServer options should be customized in /config/index.js devServer: { clientLogLevel: 'warning', historyApiFallback: { rewrites: [ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, ], }, hot: true, contentBase: false, // since we use CopyWebpackPlugin. compress: true, host: HOST || config.dev.host, port: PORT || config.dev.port, open: config.dev.autoOpenBrowser, overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false, publicPath: config.dev.assetsPublicPath, proxy: config.dev.proxyTable, quiet: True, // Necessary for FriendlyErrorsPlugin watchOptions: {poll: config.dev.poll,}}, [ new webpack.DefinePlugin({ 'process.env': require('../config/dev.env') }), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.dev.assetsSubDirectory, ignore: ['.*'] } ]) ] }) module.exports = new Promise((resolve, reject) => { portfinder.basePort = process.env.PORT || config.dev.port portfinder.getPort((err, port) => { if (err) { reject(err) } else { // publish the new Port, necessary for e2e tests process.env.PORT = port // add port to devServer config devWebpackConfig.devServer.port = port // Add FriendlyErrorsPlugin devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ compilationSuccessInfo: { messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], }, onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined })) resolve(devWebpackConfig) } }) })Copy the code
  • Webpack.base.conf: Introduces the base project configuration. Common configuration files (used by both development and production) are written here
  • Introduced plugins: copyright plugins, HTML file packaging plugins, good error prompt plugins
  • Import the merge package to merge the base configuration file with the current file.

1.2.1.2 build.js is the configuration file read during build packaging

'use strict' require('./check-versions')() process.env.NODE_ENV = 'production' const ora = require('ora') const rm = require('rimraf') const path = require('path') const chalk = require('chalk') const webpack = require('webpack') const config = require('.. /config') const webpackConfig = require('./webpack.prod.conf')...Copy the code

We see build.js introducing the webpack.prod.conf configuration file

Let’s take a look at what’s in the webpack.prod.conf configuration file

// Production environment customization const path = require('path') const utils = require('./utils') // Import webpack tool const webpack =  require('webpack') const config = require('.. /config') // introduce configuration merge tool const merge = require('webpack-merge') // introduce base configuration file const baseWebpackConfig = // require('./webpack.base.conf') // require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin' HtmlWebpackPlugin = require('html-webpack-plugin') // Introduce text package const ExtractTextPlugin = Require ('extract-text-webpack-plugin') const OptimizeCSSPlugin = Const UglifyJsPlugin = require('uglifyjs-webpack-plugin') // require('optimize- csS-assets -webpack-plugin') // Const env = require('.. /config/prod.env') const webpackConfig = merge(baseWebpackConfig, {module: {rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true }) }, devtool: config.build.productionSourceMap ? config.build.devtool : false, output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: Utils. AssetsPath ('js/[id].[chunkhash].js')}, [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false } }, sourceMap: config.build.productionSourceMap, parallel: true }), // extract css into its own file new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), // Setting the following option to `false` will not extract CSS from codesplit chunks. // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 allChunks: true, }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // See https://github.com/ampedandwired/html-webpack-plugin/packaging/HTML plugin: New HtmlWebpackPlugin({filename: config.build.index, template: {filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // keep module.id stable when vendor modules does not change new webpack.HashedModuleIdsPlugin(), // enable scope hoisting new webpack.optimize.ModuleConcatenationPlugin(), // split vendor js into its own file new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks (module) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', minChunks: Infinity }), // This instance extracts shared chunks from code splitted chunks and bundles them // in a separate chunk, similar to the vendor chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk new webpack.optimize.CommonsChunkPlugin({  name: 'app', async: 'vendor-async', children: true, minChunks: 3 }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ] }) if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8}})) if (config. Build. BundleAnalyzerReport) {const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } module.exports = webpackConfigCopy the code
  • Webpack.base.conf is introduced in prod.config.js
  • Some plug-ins were introduced: copyright configuration plug-in, HTML packaging plug-in, Text packaging tool, CSS packaging compression tool, JS compression tool.
  • The config/prod.env configuration file was read.
  • Merge basic configuration using merge

1.2.2. Babelrc configuration file: ES code related transformation configuration

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime"]
}
Copy the code

This is to convert es6 syntax to ES5. What is the goal of conversion

"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
Copy the code
  1. The market share is greater than 1%
  2. Convert the last two versions of the browser
  3. Versions later than Internet Explorer 8 do not convert

1.2.3. Editorconfig Text editing related configurations

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

Copy the code
  • Charset: Sets the character encoding format of text
  • Indent_style: The default indentation is space
  • Indent_size: The number of indent Spaces is 2
  • End_of_line: indicates the tail processing mode
  • Insert_final_newline: automatically adds a single line to the end
  • Trim_trailing_whitespace: Specifies whether to automatically format Spaces

1.2.4.eslintrc.js EsLint-related Settings

EsLint formats content configurations, and we can turn esLint on or off.

1.3. Vue access

The entry to vue is index.html when we execute

npm run dev
Copy the code

NPM run build packages files into memory. NPM run build packages files into memory. It then runs on the local server. NPM Run Build is packaged into the disk dist folder

1.3.1 Access Entry

The entry for vue access is main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

Copy the code
  • Introduced the vue
  • Introduced./ app. vue, the app. vue configuration file for the current directory
  • The dom element currently used by vue is the element with id=”app”
  • App components were introduced. App component, defined in app.vue
  • Replace elements with id=” App “with App components.

Let’s take a look at app.vue

<template> <div id="app"> <img src="./assets/logo.png"> <HelloWorld/> </div> </template> <script> import HelloWorld from  './components/HelloWorld' export default { name: 'App', components: { HelloWorld } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>Copy the code
  • The HelloWorld component was introduced first
import HelloWorld from './components/HelloWorld'
Copy the code
  • Register the component with a component named App
  • Introduce the HelloWorld component into the template

Then we see what the vUE home page looks like. Understand the source code entry, convenient for our subsequent code.