The opening

Webpack is a tool that can’t be bypassed in today’s front-end development. In particular, when developing SPA applications, both the development environment and packaging live are heavily dependent on WebPack.

The development environment

win10

Node - v: 10.15.0

NPM - v: 6.4.1

Let ‘s go.

Experience 0 Configuration

Go to the working directory and create the project

mkdir spa-webpack-demo
Copy the code

Initialize the

npm init -y
Copy the code

Let’s first experience webpack4 0 configuration:

Install webpack

npm i -D webpack
Copy the code

Once the WebPack dependencies are installed, create a SRC folder and create a new index.js in SRC.

mkdir src
cd src
type nul > index.js
Copy the code

Modify package.json by adding two commands in the scripts option:

"dev": "webpack --mode=development"."prod": "webpack --mode=production"
Copy the code

All right, we’re done. Now run the command line to test it out

npm run dev
Copy the code

Under normal circumstances, the console will have the following prompt, because the webpack command depends on webpack-CLI, we can install

Do you want to install 'webpack-cli' (yes/no): yes
Copy the code

After webpack-CLI is installed, we will automatically continue to run our NPM run dev command and see that the project has a dist directory and main.js.

Next, try NPM run prod and you can see that dist/main.js has been compressed.

This is what WebPack calls zero configuration. The main job is to define the default entry path SRC /index.js, the default output path dist/main.js, and then add a mode parameter to help us add some preset packaging rules according to the mode parameter.

Step by step

In the above process, I just experienced the feeling of zero configuration, not even the HTML file, here to add.

Add a index. HTML

Create index.html in the root directory and write anything you want

type nul > index.html
Copy the code

When it comes to handling HTML files, the htML-webpack-plugin is a must. Install it

npm i -D html-webpack-plugin
Copy the code

Then create a new webpack.config.js file in the project root directory and WebPack will use it automatically

type nul > webpack.config.js
Copy the code

The contents of webpack.config.js are as follows

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    module: {
        rules: []},plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html'.template: 'index.html'}})]Copy the code

After NPM run dev is executed, you can see that the dist folder has an index. HTML. This index. HTML automatically imports the packaged dist/main.js.

Add a local server

Index.html is generated, but you can’t open it manually and preview it in your browser every time. Webpack official recommend we use webpack-dev-server as the server

npm i -D webpack-dev-server
Copy the code

After the success of the installation, modification webpack. Config. Js, add devServer options and webpack HotModuleReplacementPlugin plug-in.

For the content that has been added to the file, I will use comments later.

const path = require('path');
const webpack = require('webpack');

function resolve(dir) {
    return path.join(__dirname, '/', dir)
}

module.exports = {
    / / module - slightly
    devServer: {
        contentBase: resolve('dist'), / / root directory
        hot: true.// Whether to enable hot replace without manually refreshing the browser
        port: 8081./ / port
        open: true.// Whether to open the browser automatically
        noInfo: true   // No packaging information is prompted, and errors and warnings are still displayed
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        / / HtmlWebpackPlugin - slightly]}Copy the code

Then change the package.json scripts dev option

"dev": "webpack-dev-server --mode=development".Copy the code

Note: When the hot devServer parameter to true, remember to add in plug-in. New webpack HotModuleReplacementPlugin (), or you can take hot on the command line parameters, so don’t need to add the plug-in to the plugins.

"dev": "webpack-dev-server --hot --mode=development"
Copy the code

Then NPM run dev is ready to try static resource hot replacement.

Handle js, CSS and other static resources

First of all, webPack itself doesn’t know how to handle static resources, but it does provide loader and plugin mechanisms.

The function of Loader, as the name implies: loader, is to match the static resources, through loader internal processing, and then return the processing results. Loader looks like an interceptor to me.

What is babel-loader? The general operation is to compile the ES6 code of the matching JS file into the corresponding ES5 code according to the configuration in the babelrc file.

So let’s just add a.babelrc file

Add. Babelrc file

type nul > .babelrc
Copy the code

Edit. Babelrc content

{
    // Pre-set, which tells Babel what new syntactic features are used in the source code to be converted
    // Targets, useBuiltIns and other options are used to compile code compatible with the target environment
    // useBuiltIns = "usage"
    // Babel introduces polyfills on demand based on the ES6/ES7 code used in the actual code and targets specified by you
    // Instead of importing import '@babel/polyfill' directly into your code, you can avoid output packages that are too large, and at the same time, you can safely use various new syntax features.
    "presets": [["@babel/preset-env", {
            // modules Whether to convert ES6's import/export modularity to Babel's CommonJs specification modularity
            "modules": false."targets": {
                // "> 1%" : supports browsers with more than 1% market share,
                // ""last 2 versions"": support the last two versions of each browser
                // "not IE <= 8": Exclude browsers below Internet Explorer 8
                "browsers": ["1%" >."last 2 versions"."not ie <= 8"]},"useBuiltIns": "usage"}]],// The plugin used
    The transform-Runtime plugin transcodes to ES5 regardless of whether the browser supports ES6 syntax
    // This should be optimized
    "plugins": ["@babel/plugin-transform-runtime"]}Copy the code

To install the Babel dependency, note:

Babel 7+ has deprecated the use of stage-x in presets and added it to plugins instead. And the NPM scope package is applied, the code is all in @babel, to avoid the previous use of babel-preset- XXX, babel-plugin-xxx

The latest babel-loader version is 8+, which depends on babel-core version 7+ with package name @babel/core, and babel-core package name for version 6+.

Reworking the.babelrc file above, it uses @babel/preset-env, @babel/ plugin-transform-Runtime, these dependencies need to be installed

Adding stage-x to plugins is not supported if @babel/preset-env is used

npm i -D babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime
Copy the code

When talking about CSS, we should think of style-loader and CSS-loader. Install them first

npm i -D style-loader css-loader
Copy the code

Install urL-loader to resolve static resources, such as images and fonts

npm i -D url-loader
Copy the code

Then modify webpack.config.js rules to add the following code

module.exports = {
    module: {
        rules: [{test: /\.js$/.loader: 'babel-loader'.include: [
                    resolve('src'),
                    resolve('node_modules/webpack-dev-server/client')]}, {test: /\.css$/.use: ['style-loader'.'css-loader'] {},test: /\.(png|jpe? g|gif|svg)(\? . *)? $/.loader: 'url-loader'.exclude: [].options: {
                    limit: 10000.name: 'img/[name].[hash:7].[ext]'}}},/ / devServer - slightly
    / / plugins - slightly
}
Copy the code
Next ready to develop, use VUE.

Vue doesn’t need to be packaged in devDependencies.

NPM i-s VUE // VUe-loader relies on vue-template-compiler and vue-style-loader NPM I-d vue-loader vue-template-compiler vue-style-loaderCopy the code

Modify webpack.config.js and add the following code

const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
    resolve: {
        extensions: ['.js'.'.vue'.'.json'].alias: {
            The '@': resolve('src')}},module: {
        rules: [{test: /\.vue$/.loader: 'vue-loader'
            },
            
            // Other - omitted]},/ / devServer - slightly
    plugins: [
        // add it first
        new VueLoaderPlugin()
        
        // Other - omitted]}Copy the code

SRC create a new views directory and assets directory.

I added a logo. PNG file in assets

Create a myTest component under views, myTest/index.vue, edit index.vue

<template> <div> <i class="logo"></i> </div> </template> <script> export default { name: 'myTest' } </script> <style scoped> .logo { display: block; margin: auto; width: 400px; height: 400px; background: url(.. /.. /assets/logo.png); } </style>Copy the code

Create a new app. vue in the SRC directory with the following contents

<template>
  <div id="app">
    <my-test></my-test>
  </div>
</template>

<script>
import myTest from "./views/myTest/index";

export default {
  name: "App".components: {
    myTest
  }
};
</script>
Copy the code

Edit the index.js file in the SRC directory as follows:

import Vue from 'vue';

import App from './App';

new Vue({
    el: '#app'.render: h= > h(App)
})
Copy the code

Finally, NPM run dev to see the effect.

The icing on the cake

Add the packing progress bar information as follows
npm i -D progress-bar-webpack-plugin
Copy the code

Modify the webpack. Config. Js

const ProgressBarPlugin = require('progress-bar-webpack-plugin');

/ /...

plugins: [
    // Other - omitted
    new ProgressBarPlugin()
]
Copy the code
Add package result message notification
npm i -D webpack-build-notifier
Copy the code

Modify the webpack. Config. Js

const WebpackBuildNotifierPlugin = require('webpack-build-notifier');

/ /...

plugins: [
    // Other - omitted
    new WebpackBuildNotifierPlugin()
]
Copy the code
Categorize package information
npm i -D webpack-dashboard
Copy the code

Modify the webpack. Config. Js

const DashboardPlugin = require('webpack-dashboard/plugin');

/ /...

plugins: [
    // Other - omitted
    new DashboardPlugin()
]
Copy the code

Modify the package. The json

"dev": "webpack-dashboard -- webpack-dev-server --mode=development"
Copy the code

I used this, the effect is not very ideal ah, will open a new window, but also can not scroll to view the information, I do not know where is wrong.

The effect is as follows:

The entire code structure is shown as follows:

Unfinished functionality

  1. productionEnvironment, need to usemini-css-extract-pluginoptimize-css-assets-webpack-pluginPlugins that extract and optimize CSS files
  2. productionEnvironment, need to useUglifyJsPluginPlugin, compress JS files, this plugin allows multi-core compilation
  3. productionEnvironment, need to useoptimizationoptionssplitChunks
  4. vue-routervuexThe introduction of
  5. , etc.

Write in the last

I hope the process of this paper can help readers who need it. In addition, the packaging function of this paper is relatively rough and the packaging speed is relatively slow. If you have any suggestions, please let me know in the comments.

Please point out if there are any mistakes. Thanks for reading.

Code address spa-webpack-demo

reference

Babel official documentation

Webpack4 + Babel7 multi-entry configuration tutorial