// webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
main: './src/index.js',
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
// 可以自己再添加一些路径
'pages': path.resolve(__dirname, '../src/pages'),
'components': path.resolve(__dirname, '../src/components'),
'common': path.resolve(__dirname, '../src/common'),
'models': path.resolve(__dirname, '../src/models'),
'utils': path.resolve(__dirname, '../src/utils')
}
},
module: {
rules: [
{
test: /\.(js|jsx)$/, // 编译 react
use: ['babel-loader'],
exclude: /node_modules/
},
{
// 图片,字体等资源,不要通过copyWebpackPlugin直接copy过去,而是正常打包,通过指定这里的 outputPath就可以了,图片字体本来就需要打包,你直接拷贝过去就没有打包了
test: /\.(jpg|png|svg|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
limit: 2048,
outputPath: 'static/images' // 打包的图片,放在 dist 的某个路径下 这里是放在dist/images下面
}
},
},
{
test: /\.(eot|ttf|svg|woff|woff2|otf)$/,
use: {
loader: 'file-loader',
options: {
name: '[name][hash:8].[ext]',
outputPath: 'static/icons'
}
}
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../src/index.html')
}),
new CleanWebpackPlugin(),
// new CopyWebpackPlugin( // 图片,字体等资源,本来就需要打包,所以不要直接copy过去,而是通过 file-loader的outputPath,指定图片打包的路径,CopyWebpackPlugin 是用来处理一些 index.html 里面引入的 脚本的
// [
// // 一次性把static 里面的文件全部拷贝过来,不需要单独写 images icons
// {
// from: path.resolve(__dirname, '../src/static'),
// to: path.resolve(__dirname, '../dist/static')
// },
// ]
// )
],
output: {
filename: '[name].[hash:8].js',
path: path.resolve(__dirname, '../dist')
},
}
//webpack.dev.js
const commonConfig = require('./webpack.common.js');
const merge = require('webpack-merge');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 是把 css文件单独提取出来,放到一个css文件里面
const devConfig = {
mode: 'development',
devtool: 'cheap-eval-module-source-map',
devServer: {
contentBase: '/dist',
hot: true,
hotOnly: true,
historyApiFallback: true, // 单页应用必须要配置这个,否则路由跳转不正确
},
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: { // 原来是用style-loader,style-loader自动帮你配置好了 hmr,现在是使用 mini, 把css文件单独提取了出来,需要配置hmr,才能让hmr生效
hmr: true, // css 的模块热替换
reloadAll: true
}
},
'css-loader'
]
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: true,
reloadAll: true
}
},
'css-loader',
'sass-loader'
]
}
]
},
optimization: {
usedExports: true,
splitChunks: {
chunks: 'all', // 对import 引入的代码都进行分割
}
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
]
};
module.exports = merge(commonConfig, devConfig);
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": 2,
}
],
"@babel/preset-react",
],
"plugins": [
"react-hot-loader/babel"
]
}
// package.json
{
"name": "houdaiyonghuguanli",
"version": "1.0.0",
"sideEffects": [
"*.css"
],
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack --config ./build/webpack.dev.js",
"server": "webpack-dev-server --config ./build/webpack.dev.js"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.6",
"clean-webpack-plugin": "^2.0.2",
"copy-webpack-plugin": "^5.0.3",
"css-loader": "^2.1.1",
"file-loader": "^4.0.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.6.0",
"node-sass": "^4.12.0",
"react-hot-loader": "^4.11.1",
"style-loader": "^0.23.1",
"url-loader": "^2.0.0",
"webpack": "^4.32.2",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.4.1",
"webpack-merge": "^4.2.1"
},
"dependencies": {
"@babel/polyfill": "^7.4.4",
"axios": "^0.19.0",
"font-awesome": "^4.7.0",
"prop-types": "^15.7.2",
"rc-pagination": "^1.20.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.1",
"sass-loader": "^7.1.0",
"simditor": "2.3.6",
"styled-components": "^4.3.2"
}
}