Business Scenario Analysis

With the booming development of the Vue and React ecosystem, we often rely on scaffolding to automatically generate project templates when developing single-page applications. Familiar commands include create-react-app project Vue create project. However, in many application scenarios, we often need to go beyond the “hothouse” of the front-end framework for development. Common examples are:

  • H5 single page production
  • Traditional web development (toJQuery.BootstrapTo accommodate older browsers such as Internet Explorer)
  • Static pages dominated by presentation
  • .

Optimal point

When you encounter the above development scenario, you may not say a word, directly open the editor, roll up your sleeves is a code shuttle. Might as well calm down, careful analysis, the general process we have the following optimization points:

  • Code changes, page automatically refreshes (no more frenetic F5 ravages)
  • Automatic handling of static resource optimization, caching, packaging, compression (reduce resource load time, reduce resource HTTP requests)
  • useES6,ES7,Sass,PostCSS. (what browser vendor prefix, import loading, easy implementation)
  • Development and production of two sets of configuration (development and production responsibilities are clear, easy to maintain)

The solution

Webpack is a static module bundler for modern JavaScript applications. When WebPack works with an application, it recursively builds a Dependency graph containing every module the application needs, and then packages all of those modules into one or more bundles. In layman’s terms, WebPack is like a chef. HTML is the raw material, and images, CSS, and JS are the spices. All we need to do is provide the ingredients and the spices, and WebPack will help us cook up a delicious dish, that is, build our Web applications.

The first tastes webpack

Let’s start with an example, using Webpack 4.x step by step to build a high reuse, functional, module clear front-end scaffolding.

Enter the following command on the command line

mkdir my-webpack && cdMy-webpack NPM init -y // NPM I NRM download NRM use taobeo switch Taobao image, increase download speed, NRM ls View the NPM source NPM I webpack webpack-cli -g // Install it globally. To install it locally, run the webpack command NPM I webpack webpack-cli -d // Because the webPack version required by the project is fixed, the global WebPack version is updated over time to prevent version conflictsCopy the code

Create webpack.config.js, SRC /index.js, dist/index.html directories as shown below

<! -- dist/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>My Webpack</title>
</head>

<body>
  <script src="bundle.js"></script>
</body>

</html>
Copy the code
// src/index.js
console.log('hello webpack! ');
Copy the code
// webpack.config.js
const path = require('path');
const pathResolve = targetPath= > path.resolve(__dirname, targetPath)

module.exports = {
  entry: { 
    index: pathResolve('src/index.js') // The entry file, that is, the js file to package
  },
  output: {
    path: pathResolve('dist'), // Where to pack the file
    filename: 'bundle.js' // The name of the package file}},Copy the code

Then in the current directory, type webpack on the command line to see

Hash: C949bc1DB5e801DF578d Version: webpack 4.28.4 Time: 377ms Built at: 2019-01-15 20:57:39 Asset Size Chunks Chunk Names bundle.js 959 bytes 0 [emitted] index Entrypoint index = bundle.js [0]  ./src/index.js 47 bytes {0} [built] WARNINGinConfiguration // Set the mode value ('development' or 'production') can remove The warning'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
Copy the code

This indicates that we have packaged successfully and that the dist folder generates bundle.js for use in index.html. Open dist/index.html as shown:

webpack
index -> bundle

Add loader and Plugin

Dist /index.html requires a handwritten

Run the following command from the command line.

npm i html-webpack-plugin style-loader css-loader url-loader file-loader -D
Copy the code

Modify the following files

/* src/index.css */
body {
  background: #ff4040;
}
Copy the code
// src/index.js
import './index.css'; // Import the CSS file
import icon from './leaf.png'; Import image URLconsole.log('hello webpack! ');

// Create an img tag to assign a value to SRC and insert the HTML document
const img = document.createElement('img');
img.setAttribute('src', icon);
document.body.appendChild(img);
Copy the code
// webpack.config.js
const path = require('path');
const pathResolve = (targetPath) = > path.resolve(__dirname, targetPath);
const htmlWebpackPlugin = require('html-webpack-plugin'); // Import the htmL-webpack-plugin
module.exports = {
  entry: {
    index: pathResolve('src/index.js'),},output: {
    path: pathResolve('dist'),
    filename: '[name].js',},module: {  // Loader focuses on processing formatted files to load various resources
    rules: [
      {
        test: /\.css$/.// Matches files that end in.css
        use: ['style-loader'.'css-loader'].// load from right to left, use csS-loader to extract CSS resources, then use style-laoder to insert  tags.
      },
      {
        test: /\.(png|jpg|jpeg|svg|gif)$/.use: [{loader: 'url-loader'.options: {
                limit: 8192.// Files smaller than 8KB are converted to dataURL:Base64. Files larger than 8KB are processed by file-loader to generate new images and package them
                name: '[name].[hash:7].[ext]'.// Hash value corresponds to the hash value of this build, which varies with each package
                outputPath: 'img'.// Output path, dist/img},},],},plugins: [ // Plugins focus on handling a specific task during webPack compilation
    new htmlWebpackPlugin({ // This plug-in can automatically generate HTML files and import static resources
      filename: pathResolve('dist/index.html'), // Generate the HTML file name
      title: 'my-webpack' // Document name})]};Copy the code

From the command line, you can see that webpack automatically generates the dist folder. Open the index.html folder under dist and you can see:

Add devServer and hot update

Is there an easy way to do this when every time we change the code, we have to type in the webpack command to rebuild, which is a headache? B: of course! We can use Webpack-dev-server to set up a local server for us to provide timely browsing and hot updates.

Enter the following command on the command line

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

Modify the following files

// package.json
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
  + "dev" : "webpack-dev-server --mode development",
  + "build": "webpack --mode production"
  },
Copy the code
// webpack.config.js
+   const webpack = require('webpack');
    module.exports = {
    +   devServer: {
            contentBase: pathResolve('dist'), // Directory of the files loaded by the local server
            port: '8080'.// Set the port number to 8080
            inline: true.// Refresh files in real time after modification (browser refresh)
            historyApiFallback: true.// When using the HTML5 History API, index.html is returned for any 404 response
            hot: true // Hot update (browser does not refresh)
        },
        plugins: [+new webpack.HotModuleReplacementPlugin(), // Hot update plugin
        +    new webpack.NamedModulesPlugin()
      ]
 }
Copy the code
// src/index.js
// ...
if (module.hot) {
  module.hot.accept() // Enable hot updates if they exist
}
Copy the code

Run NPM run dev

src/index.js

// src/index.js
+ console.log('hot replacement! ');
Copy the code

You can immediately see:

Use Sass, postCSS, separate CSS

Looking back at the files under DIST, there are no CSS-related files. There is no style label on the page of the HTML file. CSS was integrated into JS after packaging originally.

CSS
Sass
postCSS

Enter the following command on the command line

npm i mini-css-extract-plugin node-sass sass-loader postcss-loader autoprefixer -D
Copy the code

New SRC/index. SCSS

/* src/index.scss */
$link-color: #f1f1f1;

body {
  background: $link_color;
}

#avatar {
  width: 200px;
  height: 200px;
  background: url('./packet.png'); // Prepare an image larger than 8KB
  border-radius: 50%;
}
Copy the code

New SRC/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>my-webpack</title>
</head>

<body>
  <img id="avatar"></img>
</body>

</html>
Copy the code

New postcss. Config. Js

module.exports = {
  plugins: [
    require('autoprefixer') ({// A plugin for automatically managing browser prefixes
      browsers: ['last 10 versions'.'Firefox >= 20'.'Android > = 4.0'.'iOS >= 8']]}})Copy the code

Modify the following files

// src/index.js
- import './index.css';
+ import './index.scss';
Copy the code
// webpack.config.js
+   const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    module.exports = {
        module: {rules:[
        +       {
                    test: /\.(sa|sc|c)ss$/.use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: '.. / ' // CSS final path = publicPath + background: URL, set publicPath to ensure the image is obtained}},'css-loader'.'postcss-loader'.'sass-loader',],},]},plugins: [+new MiniCssExtractPlugin({
                filename: 'css/[name].[contenthash:7].css'.Contenthash Generates hash values based on CSS file contents
            }),
            new htmlWebpackPlugin({
            -    title: 'my-webpack', 
            +    template: pathResolve('src/index.html'), / / HTML templates}),],},],Copy the code

Run NPM run build, you can see that the CSS file has been separated into separate files, imported in the head as link, and automatically added webKit MOz MS compatibility vendor prefix.

conclusion

The first article focuses on what Webpack is and the use of loader and plugin so that our front-end scaffolding can handle basic business requirements. Part 2 will make further improvements to our front-end scaffolding, including but not limited to code splitting, compression, caching, and multiple pages. My level is limited, I hope you can put forward in the comments section, 😃😃😃 thank you again for reading!!

Updated how to use Webpack to improve front-end development efficiency (II)?