Webpack related
Webpack Loader and Plugin differences
-
Different functions:
Loader is a Loader. Webpack treats all files as modules, but Webpack natively only parses JS files, and if you want to package other files, you use Loader. So Loader gives Webpack the ability to load and parse non-JS files.
Our Plugin is a Plugin. Plugin can extend the functionality of Webpack to make it more flexible. A number of events are broadcast during the life cycle of a Webpack run, and the Plugin can listen for these events and change the output when appropriate through the Webpack API (understood as an extender)
-
Different usage:
Loader is configured in module.rules, that is, it exists as a parsing rule for modules. The type is array, each item is an Object, which describes the type of file (test), what to use (loader), and the parameters (options) to use.
Plugins are configured separately in plugins. Each item is an instance of plugin, and the parameters can be passed in through the constructor
Common Loader:
file
- Raw -loader Load file raw content (UTF-8)
- Val-loader executes the code as a module and exports to JS code
- Url-loader works like a file loader, but returns a data URL if the file is smaller than the limit
- File-loader sends the file to the output folder and returns the (relative) URL
JSON
- Json-loader loads JSON files (default included)
- Json5-loader loads and translates JSON 5 files
cson-loader
Load and translateCSONfile
Transpiling
- Script-loader executes a JavaScript file (such as in a script tag) once in a global context, without parsing
- Babel-loader loads the ES2015+ code and then translates it to ES5 using Babel
buble-loader
useBubleLoad the ES2015+ code and translate it to ES5traceur-loader
Load the ES2015+ code and use itTraceurTranslated into ES5- Ts-loader or awesome-typescript-loader loads typescript 2.0+ like JavaScript
- Coffee-loader loads CoffeeScript like JavaScript
Template (Templating)
- Html-loader exports HTML as a string and references static resources
pug-loader
Load the Pug template and return a functionjade-loader
Load the Jade template and return a functionmarkdown-loader
Translate Markdown to HTML- React-markdown-loader compiles markdown into the React component using markdown-parse parser
posthtml-loader
usePostHTMLLoad and convert HTML fileshandlebars-loader
Move Handlebars to HTML- Markup -inline-loader converts an inline SVG/MathML file to HTML. Useful when applying icon fonts, or CSS animations to SVG.
style
- Style-loader adds the module’s export to the DOM as a style
- Css-loader parses the CSS file, loads it using import, and returns the CSS code
- Less-loader loads and translates less files
- Sass -loader loads and translates SASS/SCSS files
- Postcss-loader Loads and translates CSS/SSS files using postCSS
stylus-loader
Load and translate the Stylus file
Linting && Testing
- Mocha – Loader using Mocha tests (browser /NodeJS)
- Eslint-loader PreLoader, which uses esLint to clean code
- Jshint-loader PreLoader: uses jshint to clear codes
jscs-loader
PreLoader, useJSCSChecking code styles- Coverjs-loader PreLoader, which uses CoverJS to determine test coverage
Framework (Frameworks)
vue-loader
Load and translateVue componentspolymer-loader
Using the selection preprocessor, andrequire()
A Web component that resembles a first-class moduleangular2-template-loader
Load and translateAngularcomponent
Common Plugin
-
Define -plugin Defines environment variables (mode is automatically configured after Webpack4)
-
Ignore-plugin ignores some files
-
Commons-chunk-plugin extracts the common code
-
Html-webpack-plugin simplifies HTML file creation (depends on htMl-loader)
-
The web-webpack-plugin makes it easier to output HTML for a single page application than the html-webpack-plugin
-
Uglifyjs-webpack-plugin does not support ES6 compression (pre-WebPack 4)
-
Terser-webpack-plugin supports compression of ES6 (webPack 5)
-
Mini-css-extract-plugin Separate style files, EXTRACT CSS as separate files, support on-demand loading (alternative to extract-text-webpack-plugin)
-
ModuleConcatenationPlugin open Scope Hoisting
-
Speed-measure -webpack-plugin Displays the execution time of each Loader and plugin (total packaging time, each plugin and Loader time).
-
Webpack-bundle-analyzer Visualizes the volume of webpack output files (business components, dependent third party modules)
In the Webpack sourcemap
Source Map is the process of mapping compiled, packaged, and compressed code back to source code. The packaged and compressed code is not very readable, and to debug the source code you need Sourcemap.
Map files will not be loaded by the browser unless developer tools are opened
There are generally three treatment options available online
-
Hidden-source-map: Used with Sentry, a third-party error monitoring platform
-
Nosource-source-map: displays only the exact number of lines and the error stack to view the source code. Higher security than Sourcemap
-
Source: Use nginx Settings to open.map files to whitelist only (Intranet)
| note: avoid using the inline – and eval – in production, because they can increase the bundle size, and reduce the overall performance
Webpack build process
The running flow of WebPack is a sequential process that follows from start to finish
- Initialization parameters: Read and merge parameters from configuration files and Shell statements to arrive at the final parameters
- Start compiling: Initialize the Compiler object with the parameters obtained in the previous step, load all configured plug-ins, and execute the object’s run method to start compiling
- Identify entry: Locate all entry files according to the entry in the configuration
- Starting from the entry file, call all configured Loader to compile the module, and then find out the module that the module depends on. In this recursive step, we know that all the entry dependent files have been processed in this step
- Complete module compilation: After the fourth step of using Loader to translate all modules, the final content of each module after translation and the amount of dependencies between them are obtained
- Output resources: Assemble chunks containing multiple modules one by one according to the dependency between the entry and modules, and convert each chunk into a separate file and add it to the output list. This step is the last chance to modify the output content
- Output complete: After determining the output content, determine the output path and file name based on the configuration, and write the file content to the file system
In the above system, Webpack will broadcast a specific event at a specific point in time, the plug-in will execute a specific logic after listening for the event of interest, and the plug-in can call the API provided by Webpack to change the running result of Webpack
The difference between Es Module and Common JS in packaging
1. Es6 module calls commonJS module
You can use commonJS modules directly. Commonjs modules will not be compiled by webPack’s module system and will be exported as is, and CommonJS modules have no default attribute
2. Es6 module invokes ES6 module
The es6 module being called does not add {esModule:true}, only the caller adds {esModule:true}, and tree-shaking is possible. If the ES6 module being called is only imported, but not used, Unused ES6 modules will be marked with /* unused Harmony default export */, which will be deleted when compressed (if the es6 module has immediate execute statements, they will be reserved).
The 3.com MonJS module references the ES6 module
Es6 modules are compiled to add {__esModule: true}. If the invoked ES6 module happens to have an export default statement, the compiled ES6 module will add the default attribute
4.commonjs module calls commonJS module
The CommonJS module will be output as-is
Expansion: modularization
Execute function immediately
In the early days, it was common to implement modularity using immediately executing functions, which solved naming conflicts and contaminated global scopes through function scopes
(function(globalVariable){
globalVariable.test = function() {}
/ /... Declaring variables and functions does not pollute the global scope
})(globalVariable)
Copy the code
AMD and CMD
Since these two implementations are rarely seen today, I won’t go into details about the features, just how they are used.
// AMD
define(['./a'.'./b'].function(a, b) {
// The module can be used after loading
a.do()
b.do()
})
// CMD
define(function(require.exports.module) {
// Load the module
// You can write require anywhere in the function body for lazy loading
var a = require('./a')
a.doSomething()
})
Copy the code
CommonJS
CommonJS was first used in Node and is still widely used today, as you can see in Webpack, but module management in Node is now a bit different from CommonJS.
// a.js
module.exports = {
a: 1
}
// or
exports.a = 1
// b.js
var module = require('./a.js')
module.a // -> log 1
Copy the code
Since CommonJS will still be used, some of the problems will be resolved here
Let’s say the require
var module = require('./a.js')
module.a
// Execute the function immediately, so as not to pollute the global variable,
// The important thing is module, which is a variable unique to Node
module.exports = {
a: 1
}
// module basic implementation
var module = {
id: 'xxxx'.I must know how to find him
exports: {} // exports is an empty object
}
Exports and module.exports are used in the same way
var exports = module.exports
var load = function (module) {
// Export things
var a = 1
module.exports = a
return module.exports
};
// Then when I require to find unique
// id, then wrap the thing to be used with the immediate execution function, over
Copy the code
Exports and module.exports are used similarly, but cannot be assigned directly to exports. Exports = module.exports var exports = module.exports indicates that exports and module.exports share the same address. However, assigning directly to exports will no longer refer to the same memory address, and this modification will not apply to module.exports.
ES Module
ES Module is a modular solution implemented natively and differs from CommonJS in the following ways
- CommonJS supports dynamic import, which is
require(${path}/xx.js)
The latter is not currently supported, but there is a proposal - CommonJS is a synchronous import, because it is used on the server, the files are local, and the synchronous import does not have much impact if the main thread is blocked. While the latter is asynchronous import, because for the browser, need to download the file, if also adopted synchronous import will have a great impact on rendering
- If the exported value changes, the imported value does not change, so if you want to update the value, you must import it again. However, the ES Module uses real-time binding. The import and export values point to the same memory address, so the imported value changes with the exported value
- ES Module will compile to
require/exports
To perform the
// Import the module API
import XXX from './a.js'
import { XXX } from './a.js'
// Export the module API
export function a() {}
export default function() {}
Copy the code
Dev – server related
Dev-server runs the configuration
- Install the NPM package for webpack-dev-server
- Webpack.config.js for configuration
Common configuration object properties in devServer are as follows
-
ContentBase: ‘./’ The directory in which the local server builds the page, usually in the current directory
-
HistoryApiFallback :true Used when building spa applications. It uses the HTML5 History Api, and any jump or 404 response can point to the index.html page
-
Inline :true is used to support the automatic refresh configuration of dev-server. Webpack has two modes to support the automatic refresh, one is iframe mode and the other is inline mode, which does not need to be configured by devServer. You only need to use a specific URL format to access it, but we generally use inline mode. If we set inline to true in devServer, we still need to configure inline to take effect when we start webpack-dev-server
-
Hot :true Enables the WebPack hot module replacement feature
-
Port: port number (default 8080)
Operation principle
- Starting the HTTP Service
- When WebPack is built, bundles are exported to memory, from which the HTTP service reads the Bundle files
- Listen for file changes and repeat the second step
Static resource access
{
devServer: {contentBase: 'public'}}Copy the code
The Proxy agent
{
devServer: {proxy: {'/api'{
target:'http://api.target.com'}}}}Copy the code
How to implement WebPack persistent cache
- Server set HTTP Cache headers (cache-control, etc.)
- Pack dependencies and runtimes into different chunks, called splitchunks, because they are almost constant
- Lazy loading: Using import(), dynamically loaded files are split into separate chunks to get their own chunkHash
- Ensure hash stability: Changes in the compilation process and file content do not affect the hash calculation of other files.
The most mature persistent caching scheme is to add a hash value after the name of a static resource, because the hash value is different each time the file is modified. The advantage of this method is to publish the file incrementally, and avoid overwriting the previous file and invalidation of online user access
Webpack hot update principle
- Webpack Compiler: Compiles JS into bundles
- Bundle Server: Provides access to files in the browser, which is essentially a Server
- HMRServer: outputs hot updated files to the HMR Runtime
- HMR Runtime: it is injected into bundle.js, linked to the HRM Server via webSocket, receives file changes and updates the corresponding files
- .bundle.js: Build the output file
1 Startup Phase
- The Webpack Compiler packages the corresponding file as bundle.js(including the injected HMR Server) and sends it to Bundler Server
- The browser accesses the server to get bundle.js
2 Update phase (file changes)
-
The Webpack Compiler is recompiled and sent to the HMR Server
-
HMR Server can know which resources and modules have changed and inform the HRM Runtime
-
HRM Runtime updates the code
Break down
basis
Start the local service with Express and respond when the browser accesses the resource
1. The server and client use Websocket to implement long connection
2. Webpack listens for changes to the source file, which triggers a webPack recompile when the developer saves the file
- Every compilation generates hash values, son files that have changed the module, js files that have changed the module code
- After compiling, push the current compiled hash stamp to the client through the socket
3. The websocket on the client listens to the hash stamp pushed by file changes and compares it with the previous hash stamp
-
Keep going cache
-
Instead, use Ajax and JSONP to get the latest resources from the server
The detailed steps
1. The server side
- Start the webpack-dev-server
- Create a WebPack instance
- Creating a Server
- Add webpack’s done event callback
- The message is sent to the client after compilation
- Create the Express application app
- Set the file system to the memory file system
- Add webpack-dev-Middleware middleware
- The middleware is responsible for returning the generated files
- Start webpack compilation
- Create the HTTP server and start the service
- Use SockJS to set up a websocket long connection between the browser and the server
- Creating a Socket server
- The client side
- The webpack-dev-server/ client listens to the hash message
- When the client receives an OK message, it performs the reloadApp method to update it
- In reloadApp, a judgment is made whether hot updates are supported, and if so, occur
- WebpackHotUpdate event, refresh the browser if not supported
- Webpack/houdev-server. js listens for the webpackHotUpdate event
- The module.hot.check method is called in the check method
- HotModuleReplacement. Runtime to request the Manifest
- By calling the e hotDownloadManifest method of jsonpmainTemplate. runtim
- Call JsonpMainTemplate. Runtime hotDownloadUpdateChunk method through the json call to get the latest module code
- Patch can call JsonpMainTemplate js back or runtime. Js webpackHotUpdate method
- Then call HotModuleReplacement. Runtime. Js hotAddUpdateChunk method dynamic update module code
- The hotApply method is then called for hot updates