rollup更适合打包库,webpack更适合打包项目,vite基于rollup实现了热更新也适合打包项目。
style-loader:实现js添加style标签
css-loader:允许js使用import 引入css文件
babel-loader:es6 - es5
html-webpack-plugin:指定模板打包
extract-text-webpack-plugin/mini-css-extract-plugin:将css独立打包成一个文件
webpack-dev-server:实现开发服务器
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
//webpack4以上的版本不再使用“extract-text-webpack-plugin”,应该改成用“mini-css-extract-plugin”; 分离css和js文件
var path = require('path');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: {
main: path.resolve(__dirname,'./main.js')
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
devServer: {
port: 8080,
hot: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
optimization: {
runtimeChunk: {
name: (entrypoint) => `runtimechunk~${entrypoint.name}`,
},
},
module: {
rules: [
{
test: /\.css$/,
// use: [
// 'style-loader',
// 'css-loader'
// ]
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
},
{
test: /\.js$/,
exclude: /node_modules/, // 如果js在node_modules则不使用
use: [
{
loader: "babel-loader",//需要安装dev:@babel/core;@babel/preset-env;babel-loader 和 生产依赖:@babel/polyfill
options: { // 放到单独的.babelrc文件
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",//此选项配置@babel/preset-env处理 polyfill。
}
]
]
}
}
],
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
inject: 'body',
scriptLoading: 'blocking'
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.SplitChunksPlugin({
chunks: 'all',
filename: "name-chunk",
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
// elementUI: {
// name: 'chunk-elementUI', // split elementUI into a single package
// priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
// test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
// },
// commons: {
// name: 'chunk-commons',
// test: resolve('src/components'), // can customize your rules
// minChunks: 3, // minimum common number代码切割之前的最小共用数量
// priority: 5,
// reuseExistingChunk: true
// }
}
})
]
};
index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>document</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
demo.css
html{
font-size: 22px;
}`
main.js
import './demo.css';
import Vue from 'vue';
/**
* webpack.config.js 配置
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
如果不配置就
import Vue from 'vue/dist/vue.esm.js'
*/
window.onload = ()=>{
var app = new Vue({
data: {
message: 'Hello Vue.js!'
},
template: '{{message}}
'
}).$mount("#app")
}
package.json
{
"name": "webpacks",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js",
"start": "webpack-dev-server --config webpack.config.js --open"
},
"author": "",
"license": "ISC",
"dependencies": {
"@babel/polyfill": "^7.12.1",
"css-loader": "^6.6.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"vue": "^2.6.14",
"webpack": "^5.68.0"
},
"devDependencies": {
"@babel/core": "^7.17.2",
"@babel/preset-env": "^7.16.11",
"babel-loader": "^8.2.3",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"mini-css-extract-plugin": "^2.5.3",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
}
}
构建上面的代码,并安装依赖,执行npm run build 和 npm run start。
webpack 的 runtime 做了什么事情:
const __webpack_modules__ = [() => {}];//维护了一个保留所有模块的数组
const __webpack_module_cache__ = {};//维护一个以moduleId为key值的cache对象
const __webpack_require__ = (moduleId) => {//维护一个引入模块的函数
const module = { exports: {} };
const m = __webpack_modules__[moduleId](module, __webpack_require__);
return module.exports;
};
__webpack_require__(0);//加载第一个模块
如何实现一个loader?
如何实现一个plugin?
.map文件:配置devtool:source-map,通常用于开发阶段,当代码出错了能够快速定位到错误文件的位置。
bundle:包/一捆,表示打包后统一的一个资源包。
chunk:块/组块,表示代码分包的单独的chunk.js,分为初始化chunk(第一次加载的首屏chunk)和异步chunk(按需加载的路由chunk)。
vendor:小贩,表示打包的第三方文件(node_modules)。
preload和prefetch:预加载和预请求,前者加载优先级高,提前加载但不立即执行,不阻塞onload,一般对切割后的代码进行preload;后者优先级低,提前请求,预测加载可能要用到的文件,一般用于路由懒加载。