Webpack是什么?
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。 ——Webpack文档
简单来说 Webpack就是一个前端项目的打包工具,精简一下就是:Webpack就是个工具
WebPack打包方式有什么特点?
WebPack以JavaScript为入口(entry);通过不同的loader,处理不同格式的资源(file资源file-loader/url-loader,css资源style-loader/css-loader,JavaScript资源babel-loader,等);通过html-webpack-plugin动态生成html文件并插入CSS、JavaScript资源;通过output配置已经处理过的文件,包括文件的名称(filename)、生成文件放置位置(path)、线上资源服务路径(publicPath),非入口文件名称(chunkFilename)等。
WebPack的常用配置是什么?
- entry WebPack的入口,打包入口文件的配置
- output Webpack的出口,输出打包后的文件配置
- mode 配置的模式 development (开发模式) / production(生产模式) / none
- module 模块的处理方式 在这里使用各种loader处理不同的资源
- plugins WebPack常用的一些插件 包括动态生成Html,将CSS生成文件等等
- devtool 调试方式 source-map等,
- resolve 设置模块如何被解析 alias 地址简写 extensions 后缀自动查找等
- context: 基础目录,绝对路径,用于从配置中解析入口起点(entry point)和 loader
WebPack的entry配置有几种常用方式?
1 './index.js'
2 {
index: './index.js'
}
3 ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true', './index.js']
4 {
index: ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true',
, './index.js']
}
第二种常在打包生成上线文件时使用,第四种模式在多页面需要进行HMR时,
第三种模式在进行SPA页面开发时,或者在优化多页面HMR过程,HtmlWebpackPlugin生成Html文件比较耗时,这时可以专注于当前开发的页面,即只打包当前开发的页面,减少需要重新生成的文件。
WebPack的output配置有几种参数?
output: {
filename: 'static/[name].js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
chunkFileName: ''
}
filename: 文件名称 可以类似static/[name].js这样书写,可以增加一个static文件夹
path 输出的路径
publicPath 服务器防止资源文件的路径
chunkFileName 非入口文件
WebPack的mode配置有几种设置?
production development none
如果不设置,按照production方式
WebPack的常用module怎么配置?
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader'
]
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images',
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts'
}
}
]
{
test: /.html$/,
loader: [
'html-loader'
]
}
}
]
}
还有bable-loader ,url-loader, postcss-loader,less-loader,vue-loader,sass-loader等等
WebPack的怎么动态生成html并插入资源文件(css,js)?
return new HtmlWebpackPlugin({
filename: `${fileName}.html`,
template: './template.html',
inject: true,
chunks: [`${fileName}`, 'vendor'],
minify: {
collapseWhitespace: true,
removeComments: true,
useShortDoctype: true,
trimCustomFragments: true,
removeTagWhitespace: true,
removeStyleLinkTypeAttributes: true,
removeScriptTypeAttributes: true,
removeRedundantAttributes: true
}
});
使用HtmlWebpackPlugin
WebPack怎么tree-shake?
使用 ES2015 模块语法(即 import 和 export)。 确保没有 compiler 将 ES2015 模块语法转换为CommonJS 模块(这也是流行的 Babel preset 中 @babel/preset-env 的默认行为 – 更多详细信息请查看 文档)。 在项目 package.json 文件中,添加一个 “sideEffects” 属性。 通过将 mode 选项设置为production,启用 minification(代码压缩) 和 tree shaking。
WebPack怎么设置模块热更新?
devServer: {
contentBase: './dist',
compress: true,
hot: true
},
使用webpack-dev-middlemare webpack-hot-middlemare
server端
const express = require('express');
const webpack = require('webpack');
const app = express();
const webpackConfig = require('./webpack.config');
const compiler = webpack(webpackConfig);
app.use(require("webpack-dev-middleware")(compiler, {
noInfo: true,
publicPath: webpackConfig.output.publicPath
}));
app.use(require("webpack-hot-middleware")(compiler));
app.listen(3000, () => {
console.log(3000);
});
webpack entry配置
const hotMiddlewareScript = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true';
{
index: ['hotMiddlewareScript', './index.js']
}
Talk is cheap. Show me the code
安装Webpack环境
mkdir learn-webpack && cd learn-webpack
npm init -y
npm install webpack webpack-cli --save-dev
touch webpack.config.js
webpack.config.js :
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const glob = require('glob');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const getEntries = () => {
return glob
.sync('src/**/*.js')
.map(url => `./${url}`);
};
const getEntryNames = () => {
const PRE_STR = './src/';
const entries = {};
getEntries()
.forEach(url => {
const removeExtUrl = url.replace(/.js$/ig, '');
const fileParamsWithPath = removeExtUrl.slice(PRE_STR.length).split('/');
entries[fileParamsWithPath.join('-')] = url.replace(/.js$/, '');
});
return entries;
};
console.log(getEntryNames());
const getWebpackHtmls = () => {
const PRE_STR = './src/';
return getEntries()
.map(url => {
const removeExtUrl = url.replace(/.js$/ig, '');
const fileParamsWithPath = removeExtUrl.slice(PRE_STR.length).split('/');
const fileName = fileParamsWithPath.join('-');
return new HtmlWebpackPlugin({
filename: `${fileName}.html`,
template: './template.html',
inject: true,
chunks: [`${fileName}`, 'vendor'],
minify: {
collapseWhitespace: true,
removeComments: true,
useShortDoctype: true,
trimCustomFragments: true,
removeTagWhitespace: true,
removeStyleLinkTypeAttributes: true,
removeScriptTypeAttributes: true,
removeRedundantAttributes: true
}
});
});
};
module.exports = {
entry: getEntryNames(),
output: {
filename: 'static/[name].js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
chunkFilename: 'static/vendor.js'
},
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
splitChunks: {
name: 'vendor',
chunks: 'all',
minChunks: 1
}
},
mode: 'production',
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader'
]
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images',
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts'
}
}
]
},
{
test: /.html$/,
loader: [
'html-loader'
]
}
]
},
plugins: [
new CleanWebpackPlugin({
dry: false,
dangerouslyAllowCleanPatternsOutsideProject: true
}),
...getWebpackHtmls(),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'style/[name].css',
chunkFilename: 'style/[id].css',
}),
new webpack.ProvidePlugin({
join: ['lodash', 'join']
})
],
resolve: {
alias: {
'@': path.resolve('./src')
},
extensions: ['.js', '.jsx', '.css', '.less', '.json', 'scss', '.vue']
}
};