Webpack4 Builds a Vue Project from scratch

Author: NCUHOME-FED Flura's blog
Authorized by the original author

Main Settings

Create Project

Create a new project folder

NPM init-y initialization package.json

Install webpack dependency packages

npm install --save-dev webpack webpack-cli webpack-dev-server

  devServer: {
    contentBase: path.join(__dirname, './dist'),
    host: 'localhost',  //  You can set 0.0.0.0 so that you can access it through 127.0.0.1 or localhost
    open: true,       //  When a project starts, it opens your browser for you by default
    port: 8088,
    // hot: true // In single-page application development, when we modify the code, the entire page is refreshed, and when the hot is turned on, only the corresponding components are refreshed
  }

Install Vue

npm install vue

npm install -D vue-loader vue-template-compiler

vue-loader webpack configuration Reference to Official Documents - Manual Settings

 // webpack.base.config.js
      const VueLoaderPlugin = require('vue-loader/lib/plugin')
  module.exports = {
  module: {
      rules: [
      // ...other rules
      {
          test: /\.vue$/,
          loader: 'vue-loader'
      }
      ]
  },
  plugins: [
      // Make sure to introduce this plugin!
      new VueLoaderPlugin()
  ]
 }

config detailed configuration

Create a new src folder, create a new index.js under the src file, and create a new webpack.config.js under the root directory

Configuration of webpack.config.js

  • webpack.config.js configuration, use of webpack-dev-server tools.

html-webpack-plugin can specify template files, which will generate html files in the output directory and introduce the packaged js.

Installation Dependency:

npm install --save-dev html-webpack-plugin

Configure rules in webpack.config.js module

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    //...other code
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'src/index.html')
        })
    ]

}
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, '/dist'),//Package Generation File Address    
    filename: 'bundle.js',
    // PublicPath:'/dist/'//Public path for file output
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: [
          "vue-loader"
        ]
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          "style-loader",
          "css-loader"
        ]
      },
      {
        test: /\.js?$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/react'],
              plugins: [
                [require("@babel/plugin-proposal-decorators"), { "legacy": true }]
              ]
            }
          }
        ],
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new htmlWebpackPlugin({
      template: './index.html'
    }),
    new VueLoaderPlugin()  // The vueLoader plugin allows you to write Vue components in a format called single file components
  ],
  devServer: {
    contentBase: path.join(__dirname, './dist'),
    host: 'localhost',  //  You can set 0.0.0.0 so that you can access it through 127.0.0.1 or localhost
    open: true,       //  When a project starts, it opens your browser for you by default
    port: 8088,
    // hot: true // In single-page application development, when we modify the code, the entire page is refreshed, and when the hot is turned on, only the corresponding components are refreshed
  }
}

Create project catalog file

Create an index.html file as the startup page in the root directory, a webpack.config.js as the webpack configuration file (there will be webpack configuration files in the actual project for the development and production environments, respectively, and for simplicity, one configuration file) and an App.vue file.

cet-query
├─ index.html start page
├─ package-lock.json
├─ package.json Package Management
├─ src
│    └─ index.js Entry File
|     └─ App.vue 
└─ webpack.config.js  webpack configuration file

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>cet-query title</title>
</head>
<body>
  
</body>
</html>

index.js

import Vue from 'vue'
import App from './App.vue'

const root = document.createElement('div') //Create div node
document.body.appendChild(root) //Add div node to body

new Vue({
  render: (h) => h(App)  //When Vue creates a Vue instance, it renders the DOM tree of the instance by calling the render method, that is, this component renders the contents of App
                        //When vue calls the render method, it passes in a createElement function as a parameter, that is, h takes the createElement function as an argument, and createElement calls with App as the parameter
}).$mount(root)

App.vue

<template>
  <div id="app">
    I am App.vue
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>

</style>

Add Startup Script

Add startup script commands in package.json

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development --progress --hide-modules",
    "dev": "webpack-dev-server --mode=development"
  },

This enables npm run dev to start successfully and npm run build to package and generate dist files

Other Extension Processing

Introducing babel-loader compatible code

babel-preset-env helps us configure babel.We just need to tell it what we want to be compatible (the target runtime environment), and it will automatically convert the code into compatible code for the corresponding environment.Escaping ES6/ES7/JSX requires Babel's dependency to support decorators.

npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread

Change webpack.config.js file

{
  test: /\.js?$/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env', '@babel/react'],
        plugins: [
          [require("@babel/plugin-proposal-decorators"), { "legacy": true }]
        ]
      }
    }
  ],
  include: path.resolve(__dirname, 'src'),
  exclude: /node_modules/
},

Configure css

Enter command to download style-loader css-loader

npm i style-loader css-loader -D

Configure rules in webpack.config.js module

{
  test: /\.css$/,
  exclude: /node_modules/,
  use: [
    "style-loader",
    "css-loader"
  ]
}

If you want to package scss or something else, install the corresponding loader.

Support for sass

Enter command to download sass-loader node-sass

npm i sass-loader node-sass -D
 Copy Code

Modify the css of webpack.config.js

{   
  test: /\.sass$/,   
  use:['vue-style-loader', 
     'css-loader', 'sass-loader' 
  ],   
  include: path.resolve(__dirname + '/src/'),    
  exclude: /node_modules/ 
},

Supporting Pictures

Enter command to download file-loader url-loader

npm i file-loader url-loader -D

Configure rules in webpack.config.js module

{   
  test: /\.(jpg|png|gif|svg)$/,   
  use: 'url-loader',   
  include: path.resolve(__dirname + '/src/'),   
  exclude: /node_modules/ 
}

Full File Reference

webpack.config.js file

const path = require('path')  //path is the basic package in Nodejs that handles paths
const htmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, '/dist'),  //Package Generation File Address    
    filename: 'bundle.js',
    // PublicPath:'/dist/'//Common path for file output
  },
  module: {  
    rules: [     //For different types of files, we define different recognition rules, the ultimate goal is to package them into js files
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: [
          "vue-loader"     //Processing.vue files
        ]
      },
      {
        test: /\.css$/,     //Processing css
        exclude: /node_modules/,
        use: [
          "style-loader",
          "css-loader"
        ]
      },
      {
        test: /\.js?$/,    //Processing js
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/react'],
              plugins: [
                [require("@babel/plugin-proposal-decorators"), { "legacy": true }]
              ]
            }
          }
        ],
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/
      },
      {
        test: /\.(png|gif|jpg|jpeg|svg)$/,     //Processing Pictures
        exclude: /node_modules/,
        use: [
          "url-loader"
        ]
      }
    ]
  },
  plugins: [
    new htmlWebpackPlugin({
      template: './index.html'
    }),
    new VueLoaderPlugin()  // The vueLoader plugin allows you to write Vue components in a format called single file components
  ],
  devServer: {
    contentBase: path.join(__dirname, './dist'),
    host: 'localhost',  //  You can set 0.0.0.0 so that you can access it through 127.0.0.1 or localhost
    open: true,       //  When a project starts, it opens your browser for you by default
    port: 8088,
    // hot: true // In single-page application development, when we modify the code, the entire page is refreshed, and when the hot is turned on, only the corresponding components are refreshed
  }
}

package.json file

{
  "name": "cet-query",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development --progress --hide-modules",
    "dev": "webpack-dev-server --mode=development"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/fuchengjx/cet-query.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/fuchengjx/cet-query/issues"
  },
  "homepage": "https://github.com/fuchengjx/cet-query#readme",
  "dependencies": {
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/plugin-proposal-decorators": "^7.4.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
    "@babel/preset-env": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "babel-core": "^6.26.3",
    "babel-loader": "^8.0.6",
    "babel-preset-env": "^1.7.0",
    "css-loader": "^3.1.0",
    "html-webpack-plugin": "^3.2.0",
    "style-loader": "^0.23.1",
    "vue-loader": "^15.7.1",
    "vue-template-compiler": "^2.6.10",
    "webpack": "^4.39.1",
    "webpack-cli": "^3.3.6",
    "webpack-dev-server": "^3.7.2"
  }
}

Keywords: Javascript Webpack Vue npm sass

Added by DoD on Tue, 06 Aug 2019 05:19:02 +0300