最近在整理自己之前的一些demo,想整一个模板工程出来,方便随时使用。之前也有用一些快速创建的脚手架,但是发现要做一些特殊配置和修改总是很麻烦,所以就自己在试着搭了一个。地址
目录结构
md
+--- README.md 说明文档
\--- build webpack相关配置
+--- webpack.prod.js 生产环境配置
+--- webpack.dev.js 开发环境配置
+--- webpack.dll.conf.js dll生成配置,用于生成dll
+--- webpack.base.js 基础配置
+--- package.json 依赖说明文件
+--- public 基础配置文件
+---build webpack相关配置
\---src 主要开发文件
+---api axios 请求封装
+---component 功能组件
+---hooks 自定义钩子
+---pages 页面组件
+---router 路由配置,(新增页面,需要在这进行配置,
+---utils 一些工具方法
+---.prettierrc 格式化配置
+---.eslintrc 代码检测配置
+---.gitignore git忽略
+---tsconfig.json ts配置
+---.env 基础环境变量
+---dev.env 开发环境变量
+---prod.env 生产环境变量
主要文件配置,及说明
webpack.base.js
- base中,读取并设置了写在
.env
里的全局变量 - 配置了地址别名
src
,因为使用的ts,所以在tsConfig.json中也要进行相应的配置 - 配置了常用的loader,ts-loader、babel-loader、sass-loader、css-loader
- 配置常用plugin,
javascript
const path = require('path');// 路径
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');// 生成HTML文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');// css压缩
const { CleanWebpackPlugin } = require('clean-webpack-plugin');// 打包清理,删除dist目录
const dotenv = require('dotenv');
// 获取环境变量,projectRoot当前目录
const projectRoot = process.cwd();
const shared = {
include: path.resolve(projectRoot, 'src'),
exclude: /node_modules/,
};
// 解析env配置文件,设置环境变量
try {
dotenv.config({ path: 'base.env' }); // 加载 .env 文件
if (process.env.NODE_ENV === 'development') {
dotenv.config({ path: 'dev.env' });
} else {
dotenv.config({ path: 'prod.env' });
}
} catch (error) {
throw new Error(`读取环境变量文件失败${error}`);
}
module.exports = {
entry: `${projectRoot}/src/index.tsx`,
cache: {
type: 'filesystem',// 使用文件缓存
},
output: {
filename: '[name].[chunkhash:8].js', // 打包后的文件名称
path: path.resolve(projectRoot, './dist'), // 打包后的目录
clean: true,
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
alias: {
src: path.resolve(projectRoot, 'src'),//使用src作为地址别名
},
},
module: {
rules: [
{
test: /.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
],
...shared,
},
{
test: /.js$/,
use: 'babel-loader',
...shared,
issuer: /.[tj]sx?$/,
},
{
test: /.s[ac]ss|css$/i,
...shared,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
issuer: /.[tj]sx?$/,
},
{
test: /.(png|svg|jpg|gif)$/,
...shared,
type: 'asset/resource',
},
{
test: /.(woff|woff2|eot|ttf|otf)$/,
type: 'asset/resource',
...shared,
},
],
},
plugins: [
/* 根据模板生成HTML文件,模板可不传 */
new HtmlWebpackPlugin({
template: `${projectRoot}/public/index.html`,
}),
/* css 文件合并 */
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
}),
// 定义环境变量,在项目文件中使用
new webpack.DefinePlugin({
'process.env.SERVER_URL': JSON.stringify(process.env.SERVER_URL),
'process.env.MODE': JSON.stringify(process.env.MODE),
}),
new CleanWebpackPlugin(),
function errorPlugin() {
// 打包错误提示
this.hooks.done.tap('done', stats => {
if (
stats.compilation.errors &&
stats.compilation.errors.length &&
process.argv.indexOf('--watch') === -1
) {
console.error(stats.compilation.errors); //错误信息
process.exit(2);
}
});
},
],
stats: 'errors-only',
};
webpack.dev.js
- 合并了上一步的基础配置,添加了开发代理,
- 后续有开发阶段的配置也可以加在这里
js
const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.base.js');
const defConfig = merge(baseConfig, {
mode: 'development',
devtool: 'source-map',//开启sourceMap,方便调试
devServer: {
proxy: [
{
context: ['/api', '/aa'],//代理
target: process.env.TEST_SERVER_URL,//在dev.env中配置
changeOrigin: true,
pathRewrite: { '^/api': '/api' },//根据自己后台配置
},
],
},
});
module.exports = defConfig;
webpack.prod.js
- 添加一些打包优化方式,terser-webpack-plugin 提高打包速度
- webpack.DllReferencePlugin 缓存文件
js
const { merge } = require('webpack-merge');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack = require('webpack');
const baseConfig = require('./webpack.base.js');
const TerserPlugin = require('terser-webpack-plugin');
//使用dll,必须在打包前先生成manifest webpack --config .\build\webpack.dll.conf.js
const manifest = require('./dist/vendor.manifest.json');
const prodConfig = merge(baseConfig, {
mode: 'production',
optimization: {
minimizer: [new TerserPlugin({//使用terser进行压缩
minify: TerserPlugin.swcMinify,
terserOptions: {},
})],
splitChunks: {
minSize: 10, // 当文件大小小于该值时,不会生成单独的chunk文件
cacheGroups: {
commons: {
// 对使用的公共文件进行抽离
name: 'commons',
chunks: 'all',
minChunks: 2, // 最小公共次数
},
},
},
},
plugins: [
// 生成dll
new webpack.DllReferencePlugin({
context: __dirname,
manifest,// manifest 就是之前打包出来的 json 文件
}),
/* css压缩 */
new CssMinimizerPlugin({
test: /.css$/,
}),
],
})
module.exports = prodConfig;
webpack.dll.conf
- 使用DllPlugin 可以将特定的类库提前打包然后引入
js
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'production',
entry: {
vendor: ['react', 'react-dom'], // 将你想要打包的第三方库列在这里
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, 'dist'),
library: '[name]_dll', // 将输出的 DLL 模块名设为全局变量
},
plugins: [
new webpack.DllPlugin({
name: '[name]_dll',
path: path.resolve(__dirname, 'dist', '[name].manifest.json'),
}),
],
};
首次 yarn build之前,需要 webpack --config webpack.dll.conf.js
生成依赖文件
tsconfig.json
- 配置地址别名必填项
baseUrl
、paths
(要和webpack.base.js里一一对应)
json
{
"exclude": [
"node_modules",
"dist"
],
"include": [
"src"
],
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"target": "es5",
"baseUrl": ".",
"paths": {
"src/*": [
"src/*"
]
},
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx"
}
}
packge.json
- 根据目录结构,配置好start、build
json
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "webpack-dev-server --config ./build/webpack.dev.js --hot --open ",
"build": "webpack --config ./build/webpack.prod.js",
"dll": "webpack --config ./build/webpack.dll.conf.js",
"lint": "eslint "src/**/*.{js,ts,tsx}" --fix"
},
快速开始
- 克隆下来就可以直接使用
- axios,和模板页面都是现成的
bash
git clone https://github.com/mobei12/React-ts-webpack.git