preface

Before we learn about Webpack, we need to understand one concept: modules.

What is a module?

If you’ve ever studied Java, C# or something like that, you probably know import in Java or using in C#.

For example: if I want to do database operations in C#, all I need to do is add these two pieces of code to the header.

using System.Data;
using System.Data.SqlClient;
Copy the code

These two pieces of code can be thought of as two modules related to database operations. When we need a database, or other operations like reading IO, we load different modules.

Obviously, this implements a very important feature in programming to load on demand.

What about modules in the front end? According to my personal understanding:

  • A module is a component in HTML
<div class="layer"> <div><%= name %></div> <% for(var i = 0; i < People.length; ++i) { %> <%= People[i] %> <% } %> </div>Copy the code
  • A module is a local style in CSS
header{
    display:block;
}
header h1{
    font-size: 60px;
}
Copy the code
  • In Javascript, a module is ascript file that encapsulates a method or data
let People = { name: "Simon"};module.exports = People;

Copy the code

How do we load modules in the front end?

Here are two very common examples:

In the Less

@import "header";
@import "layout";
@import "footer";
Copy the code

In Javascript

// CommonJS
const$=require("jQuery");

//es6
let People = { name: "Simon"};module.exports = People;

import "./layer.less";
import tpl from "./layer.ejs";
Copy the code

If you run the above code directly, the browser won’t parse it. In this case, you’ll have to rely on Webpack!

What is the Webpack

Webpack is a very popular front-end module packaging tool that can package modules loaded in a project and convert some languages that are not supported by browsers.

The packaging principle of Webpack is to find the entry file first, recursively explore all dependent modules, and finally use Loader to process different file types and package them into a Javascript file.

Among them, the two core principles of Webpack are:

  1. Everything is module
  2. According to the need to load

Of course, the role of Webpack is more than loading modules so simple, the common requirements of the front end can be realized: use Loader to transform ES6, Less, Typescript, but also use plug-ins to develop multi-page applications, and many other powerful functions.

The body of the

Next, I’ll explain how to use and configure Webpack.

The installation

I usually use Webpack in projects by executing the following four commands to install Webpack

  1. npm install -g webpack

    Executed when the Webpack is installed globally and used for the first time

  2. npm install –save-dev webpack

    Install Webpack into your project

  3. npm init

    NPM initialization, will ask for your project information, you can press Enter to skip

  4. npm install –save-dev webpack-dev-server

    In the current project, install the Webpack server

Once the installation is complete, it’s time to create the configuration file.

The basic configuration

Create a new file called webpack.config.js in the project root directory,

The general structure of a configuration file is as follows:

modules.export={
    entry: {/* Import file */
    },
    output: {/* Export file */
    },
    module: {/* Loader */
        rules:[{},{},{}]
    },
    plugins: [/ * * /].devtool: ...
    devServer: {...}
    resolve:{...}
}
Copy the code

Let’s start by analyzing the modules.export attributes

The entrance

Entry represents the entry file, the beginning of Webpack work.

Webpack recursively explores the dependent modules in the import file and uses Loader to process them in sequence.

The official website provides three data types:

  1. string
    entry: "app.js";
Copy the code
  1. An array of

    Each item in the array is packaged into an independent file

    entry: ["app.js"."main.js"];
Copy the code
  1. object

    Each property in the object is packaged into an independent file

    entry:{
        app: "./src/js/app.js".main: "./src/js/main.js"
    }
Copy the code

In general, import files are mostly module import commands such as import or require.

exit

Output As the name implies, there are four commonly used attributes for the specific configuration of a Webpack file

  1. path: ${__dirname }/dist

    Path of the packaged file

  2. filename: “js/[name].js”

    There are four common ways to write the name of a packaged file

    1. The custom

    2. [name].js

      Represents the file name of the entry

    3. [hash].js

      Hash value after the package

    4. [chunkhash]

      The hash value of the packed block

  3. publicPath: "http://cdn.com/"

    Public path when online, mainly used online

  4. chunkFilename: ‘js/[name].js’

    The name of the file output when the module is loaded on demand

Loader

Loader is the most exciting thing in Webpack!

Make any language that the browser does not support. For each file type, there are various loaders waiting to be mined.

Loader works by executing from right to left and compiling in chain order. The first loader in the loader chain returns the value to the next loader, and the last loader returns the expected result.

Loaders can be synchronous or asynchronous functions, or they can use options objects to accept configuration parameters.

infrastructure

module: {rules:[
 	   	{
  			test:/\.xxx$/.// Files ending with XXX
  			loader: "xxx-loader".exclude: {excluded path},include: {included path},options: {Loader configuration}}]}Copy the code

It is clear that Loader uses test’s regex to find various types of files, and then uses Loader to process them and convert them to browser-supported files.

There are two ways of writing loader that I know:

  1. Each loader is an object
loaders:[
 	{loader:"style-loader"},
 	{ loader: "css-loader? modules".options: { importLoaders: 1}}, {loader: "less-loader"}]Copy the code
  1. Use! The writing method of number splicing
loader: "style-loader! css-loader? importLoaders=1! less-loader"
Copy the code

The following three front-end Loader methods are mandatory

css

  1. style-loader

    Add CSS to the DOM by injecting a

    npm install style-loader --save-dev
    Copy the code
  2. css-loader

    Css-loader interprets @import and URL () like import/require () and parses them.

    npm install css-loader --save-dev
    Copy the code
  3. postcss-loader

    Adds browser prefixes for incompatible CSS properties

    npm install post-loader --save-dev
    Copy the code
  4. less-loader

    Convert Less to CSS

    npm install less --save-dev
    npm install less-loader --save-dev
    Copy the code

javascript

babel

It is used to convert ES6 to ES2015Copy the code
npm install --save-dev babel-core babel-loader babel-preset-es2015
Copy the code

Images & Fonts

  1. file-loader

    Used to compress files

    npm install --save-dev file-loader
    Copy the code
  2. url-loader

    If the file is subject to specified restrictions, it will be converted to binary encoding

    npm install --save-dev url-loader
    Copy the code

ejs

In addition, I would like to introduce my common EJS-Loader

  1. configuration
npm install --save-dev ejs-loader
Copy the code
test:/\.ejs$/ , loader:"ejs-loader".Copy the code
  1. use
<div class="layer"> <div><%= name %></div> <% for(let i = 0; i < Array.length; ++i) { %> <%= Array[i] %> <% } %> </div>Copy the code
// Import file
import tpl from "./layer.ejs";

document.body.innerHTML = tpl({
 	name:"Simon".arr: ["Apple"."Xiaomi"]});Copy the code

When you run the generated page, you will find that the EJS component has been added. Imagine if we can use a cast chart, or a leaderboard, or a comment as a component in our daily work.

The plug-in

plugins

In our daily work, we use Loaders to process different types of files, and plugins come in handy when there is a need for something else, such as pulling out CSS and generating multi-page HTML.

Plugins require that plugins be initialized in the plugins property

const htmlWebpackPlugin = require("html-webpack-plugin"); . plugins: [new htmlWebpackPlugin({/* options */})]Copy the code

Here’s a look at some of the common plug-ins you use at work

  1. clean-webpack-plugin

    It is used to clear files in the package directory before packaging to prevent file confusion.

    npm install --save-dev clean-webpack-plugin 
    Copy the code
  2. html-webpack-plugin

    Mainly used to generate HTML, you can specify template HTML, also can pass parameters for template, compressed file, etc

    npm install --save-dev html-webpack-plugin 
    Copy the code

This plug-in is a prerequisite for the front end and has many configurations

new htmlWebpackPlugin({
 	// The packaged file name
 	filename: "index.html"./ / template
 	template: "index.html".// Automatically generates script tags for true to add to HTML
 	// Or write the body/head tag name
 	inject: false.// the js injection label
 
 	/ / by < % = htmlWebpackPlugin. Options. The title % > references
 	title: The title "parameters"./ / by % > < % = htmlWebpackPlugin. The options. The date quoted
 	date: new Date(a)// The site icon
 	favicon: 'path/to/yourfile.ico'
 
 	// Generate the packaged hash
 	// If there is a hash in the file name, it means there is a reasonable buffer
 	hash: true.// Exclude blocks
  	excludeChunks: [' '].// The selected block is associated with the entry file
 	chunks: ['app'.'people']./ / compression
 	minify:{ 
 		removeComments: true.collapseWhitespace: true.minifyJS: true.minifyCSS: true.minifyURLs: true,}}),Copy the code

So how do we use parameters in template files? Write HTML files directly in accordance with EJS syntax!


      
<html lang="en">
<% = htmlWeb
    packPlugin.options.date% >
</html>
Copy the code

Generated template file


      
<html lang="en">Thu Dec 07 2017 10:01:58 GMT+0800</html>
Copy the code

In addition, if you want to build a multi-page application, just copy the above configuration several times.

new htmlWebpackPlugin({ filename: "index1.html",}new htmlWebpackPlugin({ filename: "index2.html",}new htmlWebpackPlugin({ filename: "index3.html",}Copy the code
  1. UglifyJsPlugin

    Mainly used to compress Javascript files

    npm i -D uglifyjs-webpack-plugin
    Copy the code
  2. webpack.ProvidePlugin

    Automatic loading module, global use of variables, the following with the official website DEMO

new webpack.ProvidePlugin({
  $: 'jquery'.jQuery: 'jquery'
})
// in a module
$('#item'); // <= works
jQuery('#item'); // <= works
// $is automatically set to "jquery" output
Copy the code
  1. open-browser-webpack-plugin

    Opening the server automatically opens the browser port, which is very convenient to use

  2. HotModuleReplacementPlugin

    Hot update plug-in

Common commands

  • webpack

    The most basic start webpack command

  • webpack -w

    Monitor code changes and package updates in real time

  • webpack -p

    Compress the packaged files and publish them online

  • webpack -d

    Provide SourceMaps for easy code debugging

  • webpack –colors

    The output results are colored so that you can view the information in more detail

  • webpack –profile

    Output performance data to see the elapsed time of each step

devtool

Do you have an idea now? Is the webpack file always correct? What if something goes wrong?

The devtool attribute provides the ability to generate sourcemap with the following options.

  1. source-map

    This option has the most complete source map, but slows down packaging;

  2. cheap-module-source-map

    Generates a map without a column map

  3. eval-source-map

    Package the source file module with Eval to generate a complete Source map.

  4. cheap-module-eval-source-map

    This is the fastest way to generate a Source map. The generated Source map is displayed alongside the packaged JavaScript file, but there is no column map, so use it with caution

devServer

  1. contentBase: “./dist”,

    The directory where pages are loaded by the local server

  2. historyApiFallback: true,

    The default is to point to index.html if the file cannot be found

  3. inline: true,

    The page is automatically refreshed when the source file changes

  4. hot: true,

    Hot loading on

  5. port:8080

    Set the default listening port

resolve

  1. extensions: [“.js”, “.html”, “.css”, “.txt”,”less”,”ejs”,”json”],

    Automatically extend file extensions, which means that the require module can omit them

  2. alias: { Temp: path.resolve(__dirname, “src/templates/”) }

    Module alias definition, require(‘AppStore’) directly, convenient subsequent reference alias

Other features

path

Often used for string concatenation paths.

const path = require("path");
Copy the code

There are two API

  1. path.resolve()

    Convert a relative path to an absolute path

const aPath = path.resolve("__dirname"."js"."main.js");
// aPath = the path to the main.js file in the js folder in the current directory
Copy the code
  1. path.join()

    Concatenate paths

const rPath = path.join("source"."js"."main.js");
// aPath = //source/js/main.js
Copy the code
  1. The global variable in __dirname node.js represents the current path of the project. Often used in conjunction with PATH.

Hot update

We’ve already mentioned the webpack-w command, which monitors code changes in real time to automate packaging, but has the disadvantage of not being able to refresh the interface in a timely manner.

After we start the server, we can’t use this command, at this time, if you want to do automatic packaging, but also want to automatically refresh the interface, hot update is the best choice, in addition, Webpack will only hot update the changed module, not reload the whole page, it can speed up development.

Opening steps:

  1. Modify devServer properties
devServer: {
 	hot: true.// Hot loading is enabled
 	inline: true.// The page is automatically refreshed when the file changes
}
Copy the code
  1. Add hot update plugin
const webpack = require("webpack");
//Other property
plugins: [
 	new webpack.HotModuleReplacementPlugin()
]

Copy the code

In addition, real-time updates are made only when dependent items are modified.

conclusion

Now is a Web technology boom era, we must grasp the trend of The Times.

Before writing this article, I had spent the whole day collecting almost all the Loaders and plugins I needed to work on and writing a source file. But since my source file is too large and must be displayable and hidden, otherwise it will affect reading, Markdown doesn’t support custom styles, so I posted it on my blog, hoping it will help you.

Finally, send you a welfare, if you are a personal blog lover, I recently developed a beautiful open source theme, looking forward to your use!