webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: path.join(__dirname, 'src', 'index.js'),
output: {
// custom publicPath
// publicPath: 'https://example.com'
path: path.join(__dirname, 'dist'),
filename: 'index.[chunkhash].js',
},
module: {
rules: [
{
// 匹配css
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: ['postcss-preset-env'],
},
},
},
],
},
{
// 匹配sass
test: /\.(scss|sass)$/,
use: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader'],
},
/**
* 使用 asset 处理
* asset/resource --> file-loader
* asset/inline --> url-loader
* asset/source --> raw-loader
* asset
*/
// 匹配图片
{
test: /\.(png|gif|svg|jpe?g)$/,
type: 'asset/resource',
generator: {
filename: 'img/[name].[hash:6].[ext]',
},
},
{
test: /\.(png|gif|svg|jpe?g)$/,
type: 'asset/inline',
},
{
test: /\.(png|gif|svg|jpe?g)$/,
type: 'asset',
generator: {
filename: 'img/[name].[hash:6].[ext]',
},
parser: {
dataUrlCondition: {
maxSize: 4 * 1024, // 4kb
},
},
},
{
// 字体图标处理
test: /\.(eot|svg|ttf|woff2?)$/,
type: 'asset/resource',
generator: {
filename: 'font/[name].[hash:3].[ext]',
},
},
{
// 处理js兼容
// 使用 babel.config.js
test: /\.m?jsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
exclude: [/node_modules/, /bower_components/],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'index.html'),
filename: 'index.html',
inject: 'body',
}),
new MiniCssExtractPlugin(),
],
resolve: {
// 添加引入文件时没有后缀的补充(存在默认值)
extensions: ['', '.js', '.vue', '.jsx'],
// import|require 文件时目录的简化
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
};
// index.js 热更新
if (module.hot) {
module.hot.accept(['xxx.js', () => {}]);
}
webpack.dev.js
const { merge } = require('webpack-merge'); // webpack合并工具
const path = require('path');
const common = require('./webpack.config'); // 引入公共配置
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map', // 控制台信息映射
devServer: {
hot: true,
port: 8090,
open: true, // 自动打开浏览器
compress: true, // 开启资源压缩
proxy: {
// 代理设置
'/api': {
target: 'https://api:github.com',
pathRewrite: { '^/api': '' },
changeOrigin: true,
},
},
},
});
webpack.prod.js
/**
* webpack 生产环境配置
*/
const { merge } = require('webpack-merge'); // 引入配置文件合并工具
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); // 下载
const TerserJSPlugin = require('terser-webpack-plugin');
const common = require('./webpack.config');
module.exports = merge(common, {
mode: 'production',
optimization: {
minimizer: [
new TerserJSPlugin({}), // js 混淆
new OptimizeCSSAssetsPlugin({}), // css压缩混淆
],
},
});
package.json
{
"name": "random",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npx webpack serve --config webpack.dev.js",
"build":"npx webpack --config wbpack.prod.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.16.0",
"@babel/preset-env": "^7.16.4",
"@babel/preset-react": "^7.16.0",
"asset": "^0.4.13",
"babel-loader": "^8.2.3",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.5.1",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.4.5",
"modules": "^0.4.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss": "^8.4.5",
"postcss-loader": "^6.2.1",
"postcss-preset-env": "^7.0.1",
"sass": "^1.45.0",
"sass-loader": "^12.4.0",
"source-map": "^0.7.3",
"style-loader": "^3.3.1",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.6.0",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"babel-core": "^6.26.3",
"core-js": "^3.19.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"regenerator-runtime": "^0.13.9"
}
}
项目中使用 ts
下载 ts react 需要的包
npm i @babel/preset-typescript @types/react @types/react-dom typescript -D
// webpack.config.js rules中配置
{
// 处理 ts 兼容
test: /\.tsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { useBuiltIns: 'entry', corejs: 3 }],
['@babel/preset-react'],
// 增加 ts 预设
['@babel/preset-typescript'],
],
},
},
exclude: [/node_modules/, /bower_components/],
}