Build Vue development environment from zero: webPack4 + vue-loader + KOA2 + babel-loader V8 + Babel v7 + esLint + Git hooks + EditorConfig
From 2009 to 2019 society has moved on and technology has moved on and we certainly can’t be left behind
“A thousand miles without accumulation, not small streams without rivers and oceans”
Start with the basic WebPack build
Create a project directory vue-structure
mkdir vue-structure && cd vue-structure
Copy the code
Install webpack
npm i webpack webpack-cli -D
Copy the code
Create build directory
mkdir build
Copy the code
In the build directory, create webpack.config.js
cd build && touch webpack.config.js
Copy the code
Create the entry file SRC /main.js
mkdir src
cd src && touch main.js
Copy the code
main.js
alert('hello world! ')
Copy the code
Configuration of NPM scripts
// package.json
"scripts": {
"build": "webpack --config build/webpack.config.js --progress --mode production"
}
Copy the code
Configuration devServer
npm i webpack-dev-server -D
Copy the code
Configuration of NPM scripts
"scripts": {..."dev": "webpack-dev-server --config build/webpack.config.js --progress --mode development"
}
Copy the code
HTML plugin
npm i html-webpack-plugin -D
Copy the code
Webpack configuration
// build/webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const resolve = dir => path.join(__dirname, '.. ', dir)
module.exports = {
entry: resolve('src/main.js'),
output: {
filename: '[name].[hash:5].js',
path: resolve('dist')
},
devServer: {
host: '0.0.0.0',
port: 7000,
open: true
},
plugins: [
new HtmlWebpackPlugin({
template: resolve('index.html')]}})Copy the code
Run WebPack Dev Server
npm run dev
Copy the code
The browser automatically opens http://0.0.0.0:7000/
At this point, the Webpack development service is basically running
Configure the Babel v7
webpack 4.x | babel-loader 8.x | babel 7.x
npm i -D babel-loader @babel/core @babel/preset-env
Copy the code
Babel Plugin supports dynamic import()
npm i @babel/plugin-syntax-dynamic-import -D
Copy the code
Configuration webpack. Config. Js
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
}
]
}
Copy the code
Create the.babelrc file
{
"plugins": [
"@babel/plugin-syntax-dynamic-import"]."presets": [["@babel/preset-env",
{
"modules": false}}]]Copy the code
Test the ES6 code
test.js
// src/test.js
export default () => alert('hello vue! ')
Copy the code
index.html
// src/index.html
<body>
<div id="app">请说say</div>
</body>
Copy the code
main.js
// src/main.js
document.querySelector('#app').addEventListener('click', () => {
import('./test.js').then(res => {
res.default()
})
})
Copy the code
Run dev
npm run dev
Copy the code
Click on the page div
Ok, no problem
Configure the Vue Loader
What is a Vue Loader?
Vue Loader is a Webpack Loader that allows you to write Vue components in a single file component (*.vue file) format:
Create the app. vue root component
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello Vue! '
}
}
}
</script>
<style>
.example {
color: red;
}
</style>
Copy the code
Install the Vue
npm i vue
Copy the code
src/main.js
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App)
}).$mount('#app')
Copy the code
Modified index. HTML
<body>
<div id="app"></div>
</body>
Copy the code
Run the dev
npm run dev
Copy the code
By default, webpack only recognizes JavaScript files and cannot parse. Vue files (vue single file components are unique to Vue), so the author provides vue-loader.
Vue single file component
Cn.vuejs.org/v2/guide/si…
Configure the vue – loader
npm i vue-loader vue-template-compiler
Copy the code
Vue-template-compiler (peer Dependency) is a version-dependent of vue-Loader
webpack.config.js
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin'Module. Exports = {module: {rules: [//...test: /\.vue$/,
loader: 'vue-loader'}]}, plugins: [// please make sure to introduce this plugin! New VueLoaderPlugin()]}Copy the code
The CSS in vUE single-file components also needs CSS-Loader to parse
npm i css-loader -D
Copy the code
Configuration webpack
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'}, / / it will be applied to the common ` js ` file / / and ` vue ` file ` < script > {` blocktest: /\.js$/,
loader: 'babel-loader'}, / / it will be applied to the common ` CSS ` file / / and ` vue ` file ` < style > {` blocktest: /\.css$/,
use: [
'vue-style-loader'.'css-loader'[// please make sure to introduce this plugin to cast magic new VueLoaderPlugin()]}Copy the code
NPM run dev OK, app. vue is successfully mounted to the page
CSS preprocessor configuration
npm i stylus stylus-loader
Copy the code
webpack.config.js
module: {
rules: [
{
test: /\.styl(us)? $/, use: ['vue-style-loader'.'css-loader'.'stylus-loader']]}}Copy the code
Used in vUE components
<style lang='stylus' scoped>
.example
.title
color: red
</style>
Copy the code
Postcss configuration
Postcss provides a parser that parses CSS into abstract syntax trees (AST).
npm i -D postcss-loader
Copy the code
Autoprefixer parses CSS files and adds browser prefixes to CSS content
npm i -D autoprefixer
Copy the code
Create postcss. Config. Js
module.exports = {
plugins: [
require('autoprefixer')]}Copy the code
Configuration webpack
// webpack.config.js
module: {
rules: [
...
{
test: /\.css$/,
use: [
devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true}}]}, {test: /\.styl(us)? $/, use: [ devMode ?'vue-style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'stylus-loader',
options: {
sourceMap: true}}]}Copy the code
Add cSS3 styling to app.vue
At this point, NPM run dev can see that the browser prefix is automatically added
Image resource loading configuration
url-loader
Convert the image resource to a Base64 URI
// webpack.config.js
module: {
rules: [
{
test: /\.(png|svg|jpe? g)$/, loader:'url-loader',
options: {
limit: 8192}}]}Copy the code
The image address is changed to a Base64 URI
file-loader
Loading icon fonts
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader']]}}Copy the code
cross-env
Set the environment variables for the command run time to differentiate the environment in the WebPack configuration file
npm i cross-env -D
Copy the code
package.json
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js --progress --mode production"."dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js --progress --mode development"
},
Copy the code
CSS extract
webpack4
npm i mini-css-extract-plugin -D
Copy the code
webpack.config.js
Const devMode = process.env.node_env ==='development'
module: {
rules: [
{
test: /\.css$/,
use: [
devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
'css-loader'] {},test: /\.styl(us)? $/, use: [ devMode ?'vue-style-loader' : MiniCssExtractPlugin.loader,
'css-loader'.'stylus-loader'
]
}
]
},
plugins: [
...
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'})]Copy the code
Generally, CSS extraction is not enabled in the development environment. Otherwise, the recompilation of each code change will be slow. CSS extraction is usually turned on during packaging in a build environment.
At this point NPM run build, CSS is packaged separately into a CSS file
Clearing the dist directory
Why would you want to clean up the dist directory in production because our output file is going to be a hash for cache and we’re going to concatenate the file name, and whenever we change the file name it’s going to generate a new hash, and we’re going to add a new output file every time in dist but we’re just going to compile the final one, right
NPM run build three times dist directory is as follows
Dist ├ ─ ─ app. Bundle. 0 e380cea371d050137cd. Js ├ ─ ─ app. Bundle. 259 c34c1603489ef3572. Js ├ ─ ─ App. Bundle. E56abf8d6e5742c78c4b. Js ├ ─ ─ index. The HTML └ ─ ─ style. The CSSCopy the code
module.exports = {
output: {
filename: '[name].[hash:6].js',
path: resolve('dist')}},Copy the code
Use the WebPack plug-in to clean up
clean-webpack-plugin
npm i clean-webpack-plugin -D
Copy the code
Webpack configuration
// build/webpack.config.js
const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
plugins: [
new CleanWebpackPlugin(['dist'], {
root: path.join(__dirname, '.. / ')]}})Copy the code
Then running NPM Run build cleans up the dist directory before each package
The second way is to clean up the dist directory with rimraf
rimraf
The UNIX command rm -rf for node.
npm i rimraf -D
Copy the code
Modify the package. The json
"scripts": {
"clean": "rimraf dist"."build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.js --progress --mode production",}Copy the code
NPM run build is also OK
.editorconfig
Maintain a consistent coding style for multiple developers working on the same project in different editors and IDEs.
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
Copy the code
editorconfig.org/
Code verification (Linting)
Install eslint
npm i eslint eslint-plugin-vue -D
Copy the code
Eslint various installations
npm i -D babel-eslint eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node
Copy the code
Create the.eslintrc file
{
root: true,
env: {
node: true
},
parserOptions: {
parser: "babel-eslint".sourceMap: "module"
},
extends: [
"plugin:vue/essential"."standard"
],
rules: {}
}
Copy the code
Configure ESLint in WebPack
Through webpack real-time compilation, code validation
npm i eslint-loader -D
Copy the code
webpack.config.js
module: {
rules: [
{
{
enforce: 'pre'.test: /\.(js|vue)$/,
loader: 'eslint-loader', exclude: /node_modules/ }, ...... }}]Copy the code
Define an unused variable in SRC /main.js
let title = 'eslint'
Copy the code
Run NPM run dev
Eslint is basically configured but I thought it would be nicer to report error messages on the console
eslint-friendly-formatter
A simple ESLint formatting tool/reporter that uses advanced text and iterm2 “click to open file” functionality friendly
The installation
npm i -D eslint-friendly-formatter
Copy the code
Modify the WebPack configuration
// build/webpack.config.js
module: {
rules: [
{
{
enforce: 'pre'.test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
options: {
formatter: require('eslint-friendly-formatter')}},... }}]Copy the code
NPM run dev again
In this case, error messages are displayed on the cli
devServer.overlay
Display compilation errors directly to the browser page.
webpack.config.js
module.exports = {
devServer: {
overlay: {
errors: true,
warnings: true}}}Copy the code
NPM run dev again so you can see the error message directly on the page
Configure ESLint in package.json
"scripts": {
"lint": "eslint --ext .js,.vue src"
},
Copy the code
A separate validation code through NPM is also possible
npm run lint
Copy the code
Eslint automatically fixes
How can problems detected by Eslint be fixed automatically
"scripts": {
"lint": "eslint --ext .js,.vue src"."lint:fix": "eslint --fix --ext .js,.vue src"
},
Copy the code
npm run lint:fix
Copy the code
It will automatically fix some common errors in your code
Git Hooks
Git can trigger custom scripts when certain important actions occur. Similar to the lifecycle in the framework
Git-scm.com/book/zh/v2/…
husky
npm install husky --save-dev
Copy the code
www.npmjs.com/package/hus…
Create huskyrc.
// .huskyrc
{
"hooks": {
"pre-commit": "npm run lint"}}Copy the code
package.json
"scripts": {
"lint": "eslint --ext .js,.vue src"
},
Copy the code
NPM run Lint is automatically executed every time git commit
Webpack code separation
Code separation is performance optimization (business code third party code Webpack runtime code generation…)
You can configure it directly in webpack4
// build/webpack.config.js module.exports = {optimization: {splitChunks: {// Default to bundle dependencies in node_modules into venders.js chunks:'all'}, // package the WebPack runtime generation code into runtime.js runtimeChunk:true}},Copy the code
NPM run build now sees vendors. Js and Runtime.js
See the official documentation for more configuration of the optimization option in webpack4
Webpack.js.org/configurati…
Complete configuration file at present
package.json
"scripts": {
"clean": "rimraf dist"."build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.js --progress --mode production"."dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js --progress --mode development"."lint": "eslint --ext .js,.vue src"."lint:fix": "eslint --fix --ext .js,.vue src"
},
Copy the code
build/webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const resolve = dir => path.join(__dirname, '.. ', dir)
const devMode = process.env.NODE_ENV === 'development'
module.exports = {
entry: resolve('src/main.js'),
output: {
filename: '[name].[hash:6].js',
path: resolve('dist')
},
module: {
rules: [
{
enforce: 'pre'.test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
options: {
formatter: require('eslint-friendly-formatter')}}, {test: /\.vue$/,
use: 'vue-loader',
exclude: /node_modules/
},
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true}}]}, {test: /\.styl(us)? $/, use: [ devMode ?'vue-style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'stylus-loader',
options: {
sourceMap: true}}]}, {test: /\.(png|svg|jpe? g)$/, loader:'url-loader',
options: {
limit: 8192}}, {test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader'}}, optimization: {splitChunks: {// by default, node_modules dependencies are packaged into venders.js chunks:'all'}, // Package the WebPack runtime code into runtime.js runtimeChunk:true
},
devServer: {
host: '0.0.0.0',
port: 7000,
open: true,
overlay: {
warnings: true,
errors: true
}
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
}),
new HtmlWebpackPlugin({
template: resolve('index.html')
})
// new CleanWebpackPlugin(['dist'], {
// root: path.join(__dirname, '.. / ') //})]}Copy the code
Webpack configuration source code address
Github.com/Lwenli1224/…