[webpack] theory
2021-01-28 14:16
标签:multi dup val ons tom detail -o flight const learn from https://github.com/dykily/simple_webpack and YouTube Build your own bundler and from tomotoes‘s blog A bundler lets us write modules in the processing of programming. Bundle all the modules into one single chunk JS file. So before we start, we need to be clear about Module. A static module bundler Everything can be set in Webpack views every file as a module. Data structure graph for dependencies in the whole project starting with the entry file(s). By default its value is Or specify it in Property telling webpack where to emit the bundles. By default its value is Since webpack only understands JS and JSON file. Loaders tells webpack how to process other types of files and convert them into valid modules. Loaders has two properties: Performing a wide range of tasks like bundle optimization, asset management and injection of environment variables. Invoking webpack‘s built-in optimizations when setting Please take time to see shimming for using polyfill! Further reading: tree-shaking for deleting unused code (in static structure import or export). In modular programming, developers break programs up into discrete chunks of functionality called a module. Webpack modules (can express their dependencies in a variety of ways): Webpack supports multiple types of languages and preprocessors, via loaders. Loaders describe to webpack how to process non-JS modules and include these dependencies into your bundles. See the the list of loaders or write your own. Modules APIs doc: https://webpack.js.org/api/module-methods/ Dynamically bundle all dependencies (assets). After build, in the I have no idea what is this, but that JS code dynamically generate a You can In webpack.config.js The processed image in Also use In css: Group your assets with code in a (component) directory. Use Use How can I debug in a bundled file in development mode? Source map: map bundled code to source code. Add devtool From this article, we can know that Chrome and Firefox have source map built-in. You can config the settings in chrome dev tool It quickly becomes a hassle to manually run Simply add npm script And don‘t clean The only downside is that you have to refresh your browser in order to see the changes. And add in config: This tells webpack-dev-server doesn‘t write any output files after compiling. Instead, it keeps bundle files in memory and serves them as if they were real files mounted at the server‘s root path. If you want your bundle files being referenced in It is recommended that More detail about dev-server is at https://webpack.js.org/configuration/dev-server/. Add npm script This feature allows you to split your code into various bundles which can be loaded on demand or in parallel. There are three general approaches to code splitting available: Split your code into another module. There are two pitfalls to this approach: The Use Add And add comment at After build, you can see a vendor file in webpack 4.6.0+ Tell the browser that for: You should be familiar with prefetch Preload directive has a bunch of differences compared to prefetch: Use webpackChunkname to dynamically import module. So, Files produced by webpack compilation can remain cached unless their content has changed. In filename of output, we can use bracketed strings called substitutions to template the filename. A trailing If you need to use See detail at https://nodejs.org/api/esm.html#esm_package_json_type_field Note: Files ending with When installing a package that will be bundled into your production bundle, you should use https://nodejs.org/api/modules.html Further reading: AggressiveSplittingPlugin with HTTP2 to optimize single big chunk js file https://medium.com/webpack/webpack-http-2-7083ec3f3ce6 [webpack] theory 标签:multi dup val ons tom detail -o flight const 原文地址:https://www.cnblogs.com/coyote-waltz/p/13211124.htmlLearn Webpack theory
What is a bundler
Webpack
Concepts
webpack.config.js. This file exports a config which tells webpack how to bundle files starting from the entry.Dependency graph
Entry
./src/index.js.webpack.config.jsmodule.exports = {
entry: ‘./path/to/my/entry/file.js‘
};
Output
./dist/main.jsconst path = require(‘path‘);
module.exports = {
entry: ‘./path/to/my/entry/file.js‘,
output: {
path: path.resolve(__direname, ‘dist‘),
filename: ‘my-webpack.bundle.js‘
}
};
Loaders
test (regex to match filename pattern), use (which loader to use)const path = require(‘path‘);
module.exports = {
output: {
filename: ‘my-first-webpack.bundle.js‘
},
// loaders must defined in module.rules
module: {
rules: [
{ test: /\.txt$/, use: ‘raw-loader‘ }
]
}
};
Plugins
const HtmlWebpackPlugin = require(‘html-webpack-plugin‘); //installed via npm
const webpack = require(‘webpack‘); //to access built-in plugins
module.exports = {
module: {
rules: [
{ test: /\.txt$/, use: ‘raw-loader‘ }
]
},
// put in plugins array
plugins: [
// for customize the option, you need to create an instance
new HtmlWebpackPlugin({template: ‘./src/index.html‘})
]
};
Mode
development, production or none to mode.Browser Compatibility
Modules
import
require()
define and require
@import inside a css/sass/less fileurl(...) or HTML Assets Management
Loading css
// index.js
import ‘./style.css‘;
// webpack.config.js
...
module: {
rules: [
{
test: /\.css$/,
use: [‘style-loader‘, ‘css-loader‘],
},
],
},
...
/* style.css */
body {
background-color: #efadfc;
}
bundle.js you can find code snippet like:eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \"body {\\n background-color: #efadfc;\\n}\", \"\"]);\n// Exports\nmodule.exports = exports;\n\n\n//# sourceURL=webpack:///./src/style.css?./node_modules/css-loader/dist/cjs.js");
tag in . That‘s cool!Loading Images
import image in js file or use url(...) in css.import Img from ‘./123.jpg‘; // Img is a path
myImg.src = Img;
myImg.width = ‘300‘;
box.appendChild(myImg);
// module.rules:
{
test: /\.(jpg|svg|png|gif|jpeg)$/,
use: [‘file-loader‘],
},
// ...
dist/ is minified and optiomized.Loading fonts
file-loader{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
‘file-loader‘,
],
}
@font-face {
font-family: ‘MyFont‘;
src: url(‘./my-font.woff2‘) format(‘woff2‘),
url(‘./my-font.woff‘) format(‘woff‘);
font-weight: 600;
font-style: normal;
}
.hello {
color: red;
font-family: ‘MyFont‘;
background: url(‘./icon.png‘);
}
Global Assets
Output Management
html-webpack-plugin to generate an index.html which will include all bundles with on worry about their names to reference.Cleaning up the
/dist folderclean-webpack-plugin.Development
Source map
inline-source-map in webpack.config.js devtool: ‘inline-source-map‘, // or ‘source-map‘ this will generate .map json file
Enable JavaScript source map Enable CSS source map. Only you enable the functions in dev tool, you can debug nicely.Watch mode
npm run build every time you want to compile your code."watch": "webpack --watch".index.html file after incremental build triggered by watch.// plugins
new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
Using webpack-dev-server
yarn add --dev webpack-dev-serverdevServer: {
contentBase: path.join(__dirname, ‘dist‘),
port: 8080,
hot: true,
inline: true, // reload when file changes
historyApiFallback: true, // fallback to index.html when missing other files
},
webpack-dev-server to serve the files from dist directory on localhost:8080.index.html at other path like http://localhost:8080/assets/bundle.js, config devServer.publicPath: ‘/assets/‘ . Remember the value should be surrounded with 2 slashes or a full URL.devServer.publicPath is the same as output.publicPath."start": "webpack-dev-server --open",Code splitting
entry configuration.SplitChunksPlugin to dedupe and split chunks. (dedupe: de-duplication?)Entry Points
Prevent duplication
dependOn option allows to share the modules between the chunks.dependOn: ‘module-name‘, ‘module-name‘: Array | Stringentry: {
index: { import: ‘./src/index.js‘, dependOn: ‘shared‘ },
polyfills: ‘./src/polyfills.js‘,
hello: { import: ‘./src/hello.js‘, dependOn: ‘shared‘ },
shared: ‘lodash‘,
},
SplitChunksPlugin more details in SplitChunksPlugin.optimization: {
splitChunks: {
chunks: ‘all‘
}
},
Dynamic imports
import() syntax infrom ES module.chunkFilename in output:output: {
filename: ‘[name].bundle.js‘,
chunkFilename: ‘[name].bundle.js‘,
path: path.resolve(__dirname, ‘./dist‘),
},
import(): /* webpackChunkName: "chunkName" */ (single quote is also ok)async function getComponent() {
const { default: _ } = await import(
/* webpackChunkName: ‘lodash‘ */ ‘lodash‘
).catch((err) => console.log(‘error‘));
// ...
}
dist/. (vendors~lodash.bundle.js)Prefetching/Preloading modules
tag in HTML.//...
import(/* webpackPrefetch: true */ ‘LoginModal‘);
Lazy Load
webpackChunkName comment is just an indicator which tells webpack to emit a file with name.Cache
Output Filenames
[name].[contenthash].jsResolve
resolvealiasconst path = require(‘path‘);
module.exports = {
//...
resolve: {
alias: {
Utilities: path.resolve(__dirname, ‘src/utilities/‘),
Templates: path.resolve(__dirname, ‘src/templates/‘)
}
}
};
// use
import Utility form ‘Utilities/utility‘;
$ can be added to keys to signify an exact match:const path = require(‘path‘);
module.exports = {
//...
resolve: {
alias: {
xyz$: path.resolve(__dirname, ‘path/to/file.js‘)
}
}
};
//
import Test1 from ‘xyz‘; // Exact match, so path/to/file.js is resolved and imported
import Test2 from ‘xyz/file.js‘; // Not an exact match, normal resolution takes place: node_modules/xyz/file.js
extensionsmodule.exports = {
//...
resolve: {
extensions: [‘.wasm‘, ‘.mjs‘, ‘.js‘, ‘.json‘]
}
};
// so you can import those files without extension
import file from ‘../path/to/file‘;
Tips & Extension
Enable ES module
import(ES module) in nodejs without any translator like babel, you should add "type": "module" in your package.json. However, require is not allowed at that time..js will be loaded as ES modules when the nearest parent package.json file has "type": "module"npm-package.json-pravite
npm install --save-dev
npm install --save. If you‘re installing a package for development purposes (e.g. a linter, testing libraries, etc.) then you should use npm install --save-dev.Node.js Module
AggressiveSplittingPlugin & HTTP2
上一篇:PHP 中的集合运算
下一篇:运维利器:WEB日志分析场景介绍