After 8102 years, it’s a bit late to talk about webPack configuration. Also, projects generated based on vue-CLI or create-react-app already have WebPack configured for us in one click, which doesn’t seem to require any further knowledge.

However, in order to learn and understand what front-end pain points WebPack solves, it is necessary to build a simple development environment from scratch. The webpack configuration in this article refers to the Webpack-Simple template that vuE-CLI provides. This is also the simplest webpack configuration in VUe-CLI, which is perfect for learning from scratch.

Note: This webpack is based on 3.10.0

Demo code download

Install webpack

npm i webpack -g
Copy the code

Project initialization

Create a new folder vue-webpack-simple

The new package. The json

npm init -y
Copy the code

Install vue webpack webpack-dev-server

npm i vue --save
Copy the code
npm i webpack webpack-dev-server --save-dev
Copy the code

Create index.html in the root directory


      
<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>Document</title>
</head>
<body>
    
</body>
</html>
Copy the code

Create webpack.config.js in the root directory

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

module.exports = {};
Copy the code

Create a SRC folder and create main.js under the SRC folder

The current structure of the project is as follows:

Js modular

Before ES6, JS was not a unified module system. The server side uses the CommonJS specification, while the browser side has both AMD and CMD specifications

The idea behind WebPack is that everything is a module, and the commonJS specification is officially recommended, which allows us to use commonJS modular writing on the browser side

module.exports = {}
Copy the code

Create a new util.js file under SRC

module.exports = function say() {
    console.log('hello world');
}
Copy the code

main.js

var say = require('./util');
say();
Copy the code

Modify the webpack. Config. Js

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

module.exports = {
    entry: './src/main.js'.// The project entry file, webpack will start from main.js and load and pack all dependent JS files
    output: {
        path: path.resolve(__dirname, './dist'), // The package file path of the project
        publicPath: '/dist/'.// Access path through devServer
        filename: 'build.js' // The packaged file name
    },
    devServer: {
        historyApiFallback: true.overlay: true}};Copy the code

Modify the package. Josn

"scripts": {
    "dev": "webpack-dev-server --open --hot"."build": "webpack --progress --hide-modules"
  },
Copy the code

Note: Webpack-dev-server automatically starts a static resource Web server — the hot parameter starts hot updates

Modify index.html to introduce packaged files


      
<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>Document</title>
</head>

<body>
    <script src="/dist/build.js"></script>
</body>

</html>
Copy the code

run

npm run dev
Copy the code

You can find a page that opens automatically in your browser, check the console, and it has Hello World typed

We can modify util.js at will and notice that the browser automatically refreshes, which is very convenient.

If we want to see the bundled bundle.js file, run it

npm run build
Copy the code

You can see that a dist directory is generated, which contains the bundled bundle.js

Transcoding es6 is not supported by Webpack by default, but the import export syntax is supported separately. So we can rewrite the previous modular notation

util.js

export default function say() {
    console.log('hello world ');
}
Copy the code

main.js

import say from './util';

say();

Copy the code

The introduction of vue

Let’s try to introduce vUE (single file.vue is not considered for now)

main.js

import Vue from 'vue';

var app = new Vue({
  el: '#app'.data: {
    message: 'Hello Vue! '}});Copy the code

index.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>Document</title>
</head>

<body>
    <div id="app">
        {{message}}
    </div>
    <script src="/dist/build.js"></script>
    
</body>

</html>
Copy the code

One more note: the webpack.config.js file needs to be modified

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

module.exports = {
    entry: './src/main.js'.output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/'.filename: 'build.js'
    },
    devServer: {
        historyApiFallback: true.overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'}}};Copy the code

Re-run NPM run dev, and you can see that Hello World is displayed normally

Introduce SCSS and CSS

Webpack only supports js modularity by default. If you need to import other files as modules, you need the corresponding Loader parser

npm i node-sass css-loader vue-style-loader sass-loader --save-dev
Copy the code

webpack.config.js

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

module.exports = {
    entry: './src/main.js'.output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/'.filename: 'build.js'
    },
    devServer: {
        historyApiFallback: true.overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'}},module: {
        rules: [{test: /\.css$/.use: [
                    'vue-style-loader'.'css-loader'],}]}};Copy the code

Explanation:

{
    test: /\.css$/.use: [
        'vue-style-loader'.'css-loader'],}Copy the code

Loader (CSS); loader (vue); loader (CSS); loader (vue); loader (CSS);

Note: since we are developing with VUE here, we use vue-style-loader, otherwise we use style-loader

Cs-loader allows you to import CSS in a modular way. Vue-style-loader inserts the imported CSS into the style tag of the HTML page

The same configuration is used to introduce SCSS:

module: {
        rules: [{test: /\.css$/.use: [
                    'vue-style-loader'.'css-loader'],}, {test: /\.scss$/.use: [
                    'vue-style-loader'.'css-loader'.'sass-loader'],}, {test: /\.sass$/.use: [
                    'vue-style-loader'.'css-loader'.'sass-loader? indentedSyntax']],}}Copy the code

Let’s try to create a new style directory in SRC and create common.scss in style

body {
    background: #fed;
}
Copy the code

main.js

import './style/common.scss';
Copy the code

Found CSS styles useful

Use Babel transcoding

The ES6 syntax is still not supported by most browsers, so Bable can transcode ES6 to ES5 syntax so that we can be bold and use the latest features in our projects

npm i babel-core babel-loader babel-preset-env babel-preset-stage-3 --save-dev
Copy the code

Create a new. Babelrc file in the project root directory

{
  "presets": [["env", { "modules": false}]."stage-3"]}Copy the code

Webpack.config. js adds a loader

{
    test: /\.js$/.loader: 'babel-loader'.exclude: /node_modules/
}
Copy the code

Exclude excludes the files in the node_modules folder without transcoding

Now let’s try the async await syntax util.js

export default function getData() {
    return new Promise((resolve, reject) = > {
        resolve('ok'); })}Copy the code

main.js

import getData from './util';
import Vue from 'vue';

import './style/common.scss';

var app = new Vue({
  el: '#app'.data: {
    message: 'Hello Vue! '
  },
  methods: {
    async fetchData() {
      const data = await getData();
      this.message = data;
    }
  },
  created() {
    this.fetchData(); }});Copy the code

And then the console will say regeneratorRuntime is not defined because we didn’t install babel-Polyfill

npm i babel-polyfill --save-dev
Copy the code

Then modify the entry to webpack.config.js

entry: ['babel-polyfill'.'./src/main.js'].Copy the code

Rerun NPM run dev and you can see that it is running properly

Importing image resources

Introduce images as modules as well

npm i file-loader --save-dev
Copy the code

Webpack.config. js adds a loader

{
    test: /\.(png|jpg|gif|svg)$/.loader: 'file-loader'.options: {
        name: '[name].[ext]? [hash]'}}Copy the code

Create an img directory under the SRC directory and save the image logo.png

Modify the main js

import getData from './util';
import Vue from 'vue';

import './style/common.scss';


Vue.component('my-component', {
  template: '<img :src="url" />',
  data() {
    return {
      url: require('./img/logo.png')}}})var app = new Vue({
  el: '#app'.data: {
    message: 'Hello Vue ! '
  },
  methods: {
    async fetchData() {
      const data = await getData();
      this.message = data;
    }
  },
  created() {
    this.fetchData()
  }
});

Copy the code

Modified index. 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>Document</title>
</head>

<body>
    <div id="app">
        {{message}}
        <my-component/>
    </div>
    <script src="/dist/build.js"></script>
    
</body>

</html>

Copy the code

As you can see, the image also loads correctly

Single file component

In the previous example, we used Vue.com Ponent to define global components. In real projects, single-file components are preferred

npm i vue-loader vue-template-compiler --save-dev
Copy the code

Add a Loader

{
    test: /\.vue$/.loader: 'vue-loader'.options: {
        loaders: {
            'scss': [
                'vue-style-loader'.'css-loader'.'sass-loader'].'sass': [
                'vue-style-loader'.'css-loader'.'sass-loader? indentedSyntax']}}}Copy the code

Create a new app.vue in the SRC directory

<template>
  <div id="app">
    <h1>{{ msg }}</h1>
    <img src="./img/logo.png">
    <input type="text" v-model="msg">
  </div>
</template>

<script>

import getData from './util';

export default {
  name: 'app',
  data () {
    return {
      msg: 'Welcome to Your Vue.js'
    }
  },
  created() {
    this.fetchData();
  },
  methods: {
     async fetchData() {
      const data = await getData();
      this.msg = data; }}}</script>

<style lang="scss">#app { font-family: "Avenir", Helvetica, Arial, sans-serif; h1 { color: green; }}</style>

Copy the code

main.js

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

import './style/common.scss';

new Vue({
  el: '#app'.template: '<App/>'.components: { App }
})

Copy the code

index.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>Document</title>
</head>

<body>
    <div id="app"></div>
    <script src="/dist/build.js"></script>
</body>

</html>
Copy the code

NPM run dev, you can see that the single file is loaded correctly

source-map

Debugging is also an important requirement during the development phase.

App.vue

created() {
    this.fetchData();
    console.log('23333');
}
Copy the code

So let’s intentionally hit a console, open the console

Let’s click to get to the details of the console

What I got was a packaged build.js, and I didn’t know which component it was written in, which made debugging difficult

At this point, modify webpack.config.js

module.exports = {
    entry: ['babel-polyfill'.'./src/main.js'].// omit other...

    devtool: '#eval-source-map'
};
Copy the code

NPM run dev

Packaging releases

Let’s try the NPM run build package first

As you can see, the build.js package is very large, over 500 k

In the actual release, the file will be compressed, cached, separated and other optimization

npm i cross-env --save-dev
Copy the code

Modify the package. The json

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot"."build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
}
Copy the code

This time we set the environment variable, and when we package, NODE_ENV is production

Then modify webpack.config.js and compress the JS code if NODE_ENV is production

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

module.exports = {
    / / to omit...
}

if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = '#source-map';
    module.exports.plugins = (module.exports.plugins || []).concat([
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: '"production"'}}),new webpack.optimize.UglifyJsPlugin(),
    ])
  }
  
Copy the code

repack

As you can see, the compression is very strong!

At this point, a very simple VUE development environment has been set up.

Note: The configuration in this article can be optimized in many ways, such as separating JS and CSS

It’s up to the reader to find out, but this is just a basic webPack configuration guide.