Framework technology -- Vue's webpack

Posted by Jim from Oakland on Mon, 07 Mar 2022 16:31:02 +0100

Vue framework

Vue3 Foundation: front end engineering, webpack, plugin, loader, Source Map

Vue framework is the hottest front-end framework at present. In order to cooperate with springBoot framework to complete the construction of a complete project in the later stage, we have shared the knowledge of Vue, such as ES6 modularization, Promise, EventLoop, event loop [message queue], macro tasks and micro tasks; And the tool node with Vue installed is loaded in HBuilderX

Vue

For Vue framework, we must first understand front-end engineering and webpack, which has been downloaded to global before

Front end Engineering

When I didn't touch the front-end before, maybe many people think that as long as they know Html + CSS + JavaScript, they can develop, beautify the page and send Ajax requests by using bootStrap and JQuery, and render the template structure by using art + template template template engine; But in fact, front-end development should comply with:

  • Modularization: modularization of js, css and other resources
  • Componentization: reuse the existing UI structure, style and behavior
  • Standardization: directory structure division, coding specification, interface specification, document specification, Git branch management
  • Automation: automated construction, automated deployment, automated testing

Front end Engineering: in the development of enterprise level front-end projects, standardize and standardize the tools, technologies, processes and experience used in front-end development, and finally realize the previous standards

Front end engineering can make front-end development self-contained, covering all aspects of front-end projects from creation to deployment; The development efficiency of the front-end is improved to the greatest extent, and the cost of technology selection and coordination and communication between the front and rear ends is reduced

At present, the mainstream solutions are webpack and parcel. Here is a brief introduction to webpack

webpack

Introduction to webpack

webpack is a specific solution for front-end engineering

Provide optimized front-end engineering development support, code compression, processing, browser-side JavaScript compatibility and performance optimization; It makes the work focus on the realization of functions and improves the maintainability [Maven and Spring at the back end can reduce the workload]. Most of the projects are packaged and built based on webpack

Project creation instance: List interlaced color change

  • To create a new project, npm init -y can initialize the package management file package JSON - here, directly create an empty project webpack in HBuilderX, and then run the command npm init -y to use ES6, so add type: module
{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  • New src source directory

  • New SRC - > index HTML homepage and Src - > index JS script file

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
        <script src="./index.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<ul>
			<li>This is the first one li</li>
			<li>This is the second li</li>
			<li>This is the third li</li>
			<li>This is the fourth li</li>
			<li>This is the fifth li</li>
		</ul>
	</body>
</html>

-----------------use npm Command introduction jquery-------------------Operate the above dom
  • Initialize the basic structure of the home page

  • Run npm install jquery -S to install JQuery

PS D:\HBuilderX\Web project\webpack> npm i jquery  -S

added 1 package in 2s

After importing the package, a node is used in the project_ Modules to store the downloaded and imported packages, so that you can use the default import and use the packages under this directory in other js files [so that there is no need to use script tags to link js scripts as originally]

  • Import JQuery through ES6 modularization to realize list interlaced color change
//Import JQuery
import $ from 'jquery'
//Interlaced color change
$(function(){ //Automatically execute after the page is loaded -- equivalent to the load event
	//The selector selects the tag to modify the attribute, odd represents the cardinality, and ene belongs to filtering
	$('li:odd').css('backgroundColor','red')
	$('li:even').css('backgroundColor','green')
})

Error: unable to import module; This is because browsers are not compatible; webpack can solve these compatibility problems - automatically convert the code with compatibility problems into the code without compatibility, and then run it to the browser

Install the webpack for the project. Use the command to install two packages. It is only used during development, so it is - D

npm i webpack@5.5.1 webpack-cli@4.2.0 -D


PS D:\HBuilderX\Web project\webpack> npm i webpack@5.5.1 webpack-cli@4.2.0 -D
added 136 packages in 6s

Configure webpack in project

  1. In the root directory of the project, create a file named webpack.com config. Configuration file of webpack of JS
//Here we simply declare the configuration object
module.exports ={
	mode: 'development'  //The mode values include development and production, and dev is used in the development stage
}
  1. In package Add dev script in script [runnable Script] of JSON; Use npm run XX to run the script; npm run dev ; Dev here is arbitrary, but the value is webpack; Running the dev script will start the webpack and then read it config. JS to read configuration items and package the project
 "scripts": {
   //"Test": "echo error: no test specified & & Exit 1"
	"dev" : "webpack"
  },

After running npm run dev, the dist directory will be generated, which is shown as main js is the index before the webpack solution The new js file generated after js compatibility is reintroduced

above test It's best to delete it, because sometimes it may report an error

//There was a small problem here before
[webpack-cli] Error [ERR_REQUIRE_ESM]: require() of ES Module D:\HBuilderX\Web project\webpack\webpack.config.js from D:\HBuilderX\Web project\webpack\node_modules\webpack-cli\lib\groups\resolveConfig.js not supported.

This is because I joined before type : module ; Here to use require(),This is CommonJS,So delete it

You can intercept a short section of main JS take a look

/************************************************************************/
/******/ 	/* webpack/runtime/compat get default export */
/******/ 	(() => {
/******/ 		// getDefaultExport function for compatibility with non-harmony modules
/******/ 		__webpack_require__.n = (module) => {
/******/ 			var getter = module && module.__esModule ?
/******/ 				() => module['default'] :
/******/ 				() => module;
/******/ 			__webpack_require__.d(getter, { a: getter });
/******/ 			return getter;
/******/ 		};
/******/ 	})();

All js files have been processed here, and require is used to directly link this file to index HTML can solve the compatibility problem

<script src="../dist/main.js" type="text/javascript" charset="utf-8"></script>

After modifying the js file, if there is no hot update, you need to rerun the npm run dev command to execute the webpack

Optional value of module [in webpack.config.js]

webpack.config.js is the configuration file of webpack. After the webpack really starts to package and build, it will first read the configuration file, so as to package the project based on the given configuration; Webpack is based on node JS development tools, so the configuration file supports the use of node JS syntax for personalized configuration [CommonJS]

  • development

It refers to the development environment, which will not compress the code and optimize the performance of the files generated by packaging, so the packaging speed is fast and suitable for use in the development stage

  • production

The production environment will compress the code and optimize the performance of the files generated by packaging, so the packaging speed should be slower, which is suitable for use after the completion of project development

The default package entry file in webpack is SRC - > index js

The default output file path is dist - > main js

If you want to modify the default value, you need to change it in webpack config. JS configuration file. The syntax CommonJS of node is used here to introduce the path package: entry refers to the packaging entry, output refers to the packaging exit, and path and filename specify the path and name of the exit respectively

const path = require('path') //CommonJS introduces path package

module.exports ={
	mode: 'development',//The mode values include development and production, and dev is used in the development stage
	entry: path.join(__dirname,'./src/index.js'), 
	output: {
		path: path.join(__dirname,'./dist'),
		filename: 'boundle.js'
	}
}

Path used Join to splice paths [because this is a relative path]

Front end relative path /. //

  • No / is the resource path. As mentioned before, here and/ Is the same/ Both and resource paths indicate that the relative path is the directory path where the current file is located
  • /It is a relative path. If it is a web project, it is the path before the project path, which is the port number level. Generally, it is the upper level directory of the project
  • ... / means to return to the upper level directory, that is, the upper level directory of the directory where the previous file is located is the relative path
  • ... /... / is another level, and so on

Here, delete the previous dist and re execute the command. It is found that the modification is successful

plugin in webpack

After the above code is modified each time, npm run dev must be re run to execute webpack. You can use plugin for hot update. You can expand the capability of webpack by installing and configuring third-party plug-ins

  • webpack-dev-server

    • Similar to node JS command nodemon, hot update; Whenever the source code is modified, webpack will automatically package and build the project

    • [- D represents recording it to the development node], run the command NPM I webpack dev- server@3.11.0 -D. After downloading, you need to configure it into the project

    • Configuration: modify package The dev command in JSON - > scripts, which was previously webpack, is executed directly without hot update

      "dev": "webpack serve"
      
      
      //After modification, run npm run dev to access real-time updates through the browser. Similar to nodemon, if an error is reported, use NPM I webpack cli - D to update and then use it
      
      
      
      ---------------------result-----------------------
      PS D:\HBuilderX\Web project\webpack> npm run dev
      
      > webpack@1.0.0 dev
      > webpack serve
      
      (node:552) [DEP0111] DeprecationWarning: Access to process.binding('http_parser') is deprecated.
      (Use `node --trace-deprecation ...` to show where the warning was created)
      × 「wds」:  Error: listen EACCES: permission denied 127.0.0.1:8080 ---- netstat Kill it
          at Server.setupListenHandle [as _listen2] (node:net:1313:21)
          at listenInCluster (node:net:1378:12)
          at GetAddrInfoReqWrap.doListen [as callback] (node:net:1516:7)
          at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:73:8) {
        code: 'EACCES',
        errno: -4092,
        syscall: 'listen',
        address: '127.0.0.1',
        port: 8080
      }
      

    It should be noted that webpack server will start a batch of real-time packaged HTTP servers, so check the packaging effect in http://localhost:8080 ; The effect here is the same as that of the previous nodemon mounting server; The port number may be occupied here. You can turn it off first

    After opening this URL, the directory structure of the project appears, including dist, so click src to run index html; However, after direct modification, the browser does not change immediately, because the packaged files after configuring the plug-in are stored in the cache

    Destination of packaged files

    1. Without configuring the webpack dev server, the files generated by webpack packaging are directly put on the physical disk [strictly follow the configuration in webpack.config.js and the specified path of the output node]
    2. After configuration, the files generated by packaging are stored in memory [no longer put in disk to improve the performance of real-time packaging output, because the speed of memory is faster] the files generated by webpack dev server into memory are placed in the root directory of the project by default and are virtual and invisible, which can be 8080 / bundle JS view a file
    <!--So it needs to be modified here index.html The path of the reference in is no longer dist Instead, under the root directory of the project, use/Relative path, so/ ->The foreground path can represent the above web address -->
    <script src="/boundle.js" type="text/javascript" charset="utf-8"></script>
    
    Saving will automatically update the page nodemon
    
  • html-webpack-plugin

    The HTML plug-in in webpack is similar to a template engine plug-in; You can customize the index through this plug-in HTML content

    Install: use the command NPM I HTML webpack plugin - D to install directly to the latest version

    Configuration: open webpack config. js

    //1. Use commonJS syntax to import HTML webpack plugin package
    const HtmlPlugin = require('html-webpack-plugin')
    
    //2. Create an instance object of html plug-in
    const htmlPlugin = new HtmlPlugin({
    	template: './src/index.html',//Specify the storage path of the source file
    	filename: './idex.html'  //Specify the storage path of the generated file
    })
    
    //In module In exports, add node plugins
    plugins: [htmlPlugin]  //Make HtmlPlugin effective through the plugin node
    

    Example: through the HTML webpack plugin plug-in, index. Under src Copy a copy of the HTML home page to the root directory, and you can index.html through template and filename Copy a copy of HTML to the root directory [browser memory] and copy the HTML plug-in to IDEX in the root directory HTML page, put in memory; And the bottom of the page is automatically injected with packaged bundles JS file, < script defer src = "boundary. JS" > < / script > so there is no need to inject manually

    After real-time packaging is enabled, add an html plug-in to delete the dist directory because it no longer depends on the bundle under it JS file, but a virtual file in the temporary root directory

    <!-- <script src="../dist/boundle.js" type="text/javascript" charset="utf-8"></script> -->
    

    [you can end nodemon command by pressing CTRL + C twice, and cls command can clear the screen]

  • devserver node

    On webpack config. JS configuration file, you can configure the webpack dev server plug-in more through the devServer node. Open specifies whether to open automatically, and host and port specify the port number; The configuration node is at the same level as the previous module,output, entry and plugins

    devServer:{
    		open: true,  //Represents whether to open automatically
    		host: '127.0.0.1',  //Here is the string form
    		port:8090  //In this way, there will be no occupation
    	}
    

The settings here are the same as the nodemon configuration server in the previous ES6 instance; You need to reconfigure the server

loader in webpack

In actual development, webpack can only be packaged by default js suffix module, other non js at the end of the module, such as css cannot be processed. At this time, we need to use the loader loader to package

The role of loader loader: assist webpack to package and process the specified file module

  • css loader: it can be packaged css related files
  • less loader: it can be packaged less related documents
  • Babel loader: it can package and handle Advanced JS syntax that webpack cannot handle

Calling process of loader:

First judge the module to be processed. If it is JS, judge whether there is advanced JS syntax. If not, package it directly. Otherwise, judge whether to install and configure the relevant loader

In webpack, everything is a module; So any module such as css can be imported into js

Package css files

The above operation can be continued here HTML, add style to it, and create css folder under src directory,

Index HTML [remove the * in front of the list]

ul:{     ----> This is the wrong way to write. The selector should be followed directly{},add: stay firefox Warning in
	list-style: none;
}

--------------It's just a selector plus{style}---------------
ul{
	list-style: none;
}

To make this css file effective, link will be linked in as before. Now, according to the modular thinking, it will be directly imported into index JS

import  './css/index.css' //Just execute, not use, so add the path directly
  • Run the command - i-style-loader, css-loader-m-style-loader directly
  • Configuration: in webpack config. In the modlue - > rules array in JS, add the loader rule. test and use specify the suffix and its loader respectively; Style loader before CSS loader
const path = require('path') //CommonJS introduces path package

//1. Use commonJS syntax to import HTML webpack plugin package
const HtmlPlugin = require('html-webpack-plugin')

//2. Create an instance object of html plug-in
const htmlPlugin = new HtmlPlugin({
	template: './src/index.html',//Specify the storage path of the source file
	filename: './index.html'  //Specify the storage path of the generated file
})

module.exports ={
	mode: 'development',//The mode values include development and production, and dev is used in the development stage
	entry: path.join(__dirname,'./src/index.js'), 
	output: {
		path: path.join(__dirname,'./dist'),
		filename: 'boundle.js'
	},
	plugins: [htmlPlugin],  //Make HtmlPlugin effective through the plugin node
	devServer:{
		open: true,  //Represents whether to open automatically
		host: '127.0.0.1',
		port:8090  //In this way, there will be no occupation
	},
	module:{ //Matching rule identification of all third-party file modules
		rules:[ //Matching rules for file suffixes
			{test:/\.css/,use:['style.loader','css.loader']} //test is regular and the file is regular; use is the loader used
		]
	}
}

Restart the server and package after running

Can’t resolve ‘style. 'loader' problem

This is because we have installed a higher version of webpack, so the configuration syntax is not the same as before. In webpack 4 After XX, the loader must be specified in the form of object when configuring the loader, that is, use:[{loader:xxx},......]

module:{ //Matching rule identification of all third-party file modules
		rules:[ //Matching rules for file suffixes
			{ test: /\.css/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' }] } //test is regular and the file is regular; use is the loader used
		]
	}

Here we need to note that loader must be preceded by loader:

Package and process less files

The less file can operate on the margin, padding and other locations, so let's beautify the previous list and create a new index under css Less file

html,body,ul{
	margin: 0;
	padding: 0;
	li{
		line-height: 35px;
		padding-left: 10px;
		font-size: 12px;
	}
}

Then in index Import the module 'import' into JS/ css/index. 'less', if you want to package, you still need to install and configure two loader s

Installation: NPM I less loader less - D

Configuration: {test: /. Less $/, use: [{loader: 'style loader'}, {loader: 'css loader'}, {loader: 'less loader'}]} / / use style and css instead of less. Less is a built-in dependency of less loader

Package the url related file url loader file loader in the stylesheet

Now create a new div with id box on the index to set Src / img / local Png as the background picture of the box

Normally, in index Under less, the div style will be edited

#box{
	width: 380px;
	height: 114px;
	background-color: yellow;
	background: url(../img/local.png);
}

You may need an appropriate loader to handle this file type jpg,.png ending file

Installation: NPM I URL loader file loader - D install two loaders

Configuration: {test: / \. Jpg|png|gif $/, use: [{loader: 'URL loader'}]} / / only URL loader is configured for the time being, and various suffixes of images are used|

Then run it again: but the background of div is part of the captured picture

URL loader parameter limit

In web pages, small images can be directly converted into base64 and loaded directly, and large images can be re requested, which can improve the performance of web page access. Selecting the size requires the URL loader parameter limit, and those less than or equal to base64. Limit is used to specify the size of the image, and the unit is byte

{ test: /\.jpg|png|gif$/,use:[{loader: 'url-loader?limit=207946'}]

After setting, you can view the picture again: url(data:image/png;base64 - > is changed to base64

Other methods of loader configuration

The loader can be configured in the form of object:

use:{
    loader:'url-loader' , //The loader property points to the called loader
    options:{
        limit:2229  //Specify parameter items through options
    }
}

High level syntax for packaging and processing js files

Webpack can only package and process part of the advanced js syntax. For the advanced js syntax that cannot be processed by webpack, you can only use Babel loader to assist in packaging; The latest version of webpack can handle

class Person{
	//Declare a static attribute for the Person class using static
	//This advanced syntax, webbal static, cannot be used
	static info = 'person info';
}

Babel loader contains three main packages, Babel loader, @ babel/core, @ Babel / plugin proposed class properties

Installation: NPM I Babel loader @ Babel / core @ Babel / plugin proposed class properties - D

Configuration: note that in addition to test and use, there is an exclude item: 'node'_ modules’; Babel loader only needs to process the js file written by the user, not node_ Download other package files under modules, which is fast

{
				test: /\.js$/,
				exclude:/node_modules/ ,  //Here is also regular
				use:{//To declare the plug-in, it is used to convert the high-level syntax. The following @ starts with the plug-in
					loader: 'babel-loader',
					options:{
						plugins:['@babel/plugin-proposal-class-properties']
					}
				}
			}

The above is an item of the rules array

Packaging and publishing

After the project is completed, use webpack to package and publish the project:

  • In the development environment, the files generated by packaging are stored in memory, and the final generated files cannot be obtained
  • In the development environment, the mode is development, and the code will not be compressed and performance optimized, so it needs to be packaged and released

Configure the packaging and publishing of webpack

Package before The dev command is configured under the scripts node under JSON, which represents development. When the project is completed, reconfigure the command build

'build': 'webpack --mode production'  //There is no serve, so the server plug-in is not used. It is directly placed on the physical disk, and the webpack.com will be modified at the same time config. If the mode of JS is production, it will be compressed

The value of mode in config will be overwritten here

This uses the command npm run build

Unified location of generated files

The files generated directly are messy. To uniformly generate js files into the js directory, you need to configure them in output

//The generated location filename can be added with js level
output: {
		path: path.join(__dirname,'./dist'),
		filename: 'js/boundle.js'
	}

For image files generated to img directory, the URL loader needs to be configured. In addition to the original limit parameter, add an outputPath parameter to specify the path

{ test: /\.jpg|png|gif$/,use:{
				loader: 'url-loader',
				options:{
					limit:227946,
					outputPath:'image'
				}
				}}

Automatically clean up dist directory

In order to automatically clean up the dist directory for each package release, install the configuration plug-in clean webpack plugin NPM I XX - D

Installing and configuring this plug-in is the same as configuring the html plug-in before

const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()

//1. Use commonJS syntax to import HTML webpack plugin package
const HtmlPlugin = require('html-webpack-plugin')

//2. Create an instance object of html plug-in
const htmlPlugin = new HtmlPlugin({
	template: './src/index.html',//Specify the storage path of the source file
	filename: './index.html'  //Specify the storage path of the generated file
})

module.exports ={
	mode: 'development',//The mode values include development and production, and dev is used in the development stage
	entry: path.join(__dirname,'./src/index.js'), 
	output: {
		path: path.join(__dirname,'./dist'),
		filename: 'js/boundle.js'
	},
	plugins: [htmlPlugin,cleanPlugin],  //Make HtmlPlugin effective through the plugin node

In the advanced packaging release, including packaging and generating reports, analyzing specific optimization bills, tree shaking, providing CDN loading for third-party libraries, configuring on-demand loading of components, enabling lazy loading of routes, and customizing the contents of the home page

Source Map

Problems encountered in the production environment: after the front-end projects are put into the production environment, the js files need to be compressed and confused, so as to reduce the volume and improve the loading efficiency, but there is a problem: the compressed code is not easy to debug

Source Map is an information file that stores the location information and the corresponding relationship between the location before and after code compression. With Source Map, when an error occurs, the error tool directly displays the source code instead of the converted code, which is convenient for later debugging

In the development environment, webpack turns on the Source Map function by default. When an error occurs, the console displays the location of the wrong line and locates the specific source code, but there are some problems by default. The default is the location of the code after production, and the number of lines is inconsistent

In webpack config JS file, which is at the same level as model

module.exports ={
	mode: 'development',//The mode values include development and production, and dev is used in the development stage
	devtool: 'eval-source-map',   -----------------------------------------Added configuration
	entry: path.join(__dirname,'./src/index.js'), 
	output: {
		path: path.join(__dirname,'./dist'),
		filename: 'js/boundle.js'
	},
	plugins: [htmlPlugin,cleanPlugin],  //Make HtmlPlugin effective through the plugin node
	devServer:{
		open: true,  //Represents whether to open automatically
		host: '127.0.0.1',
		port:8090  //In this way, there will be no occupation
	},
	module:{ //Matching rule identification of all third-party file modules
		rules

After configuration, the number of rows is consistent

Source Map in production environment

In the production environment, omit the devtool option, and the final generated file does not contain the Source Map, which can prevent the disclosure of the original code through the Source Map. In this way, the dislocation of positioning is the confused code of transformation. If it is not good for debugging, it can be set as: only the number of lines is displayed, and the code is not exposed

devtool: 'nosources-source-map'

This is convenient for debugging and will not reveal the code

However, devtool: 'source map' can locate the source code. It has the same effect as the previous Eval source map of the development environment. It is very unsafe. Generally, it uses nosources or closes it directly 🎄

Topics: Java Javascript Vue.js Webpack server