项目初始化
npm init
react配置
npm i react react-dom
npm i @types/react @types/react-dom -D
npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/polyfill
npm i core-js@2 # babel的按需引入依赖
npm i -D @babel/plugin-proposal-class-properties # 能够在class中自动绑定this的指向
npm i -D typescript awesome-typescript-loader # 处理ts,主要就靠它
npm i -D html-loader html-webpack-plugin # 顺便把html的支持做好
Webpack配置
npm i -D webpack webpack-cli webpack-dev-server webpack-merge
具体配置
const path = require('path');
const webpack = require('webpack');
const config = require('./config');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const argv = require('yargs').argv;
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const merge = require('webpack-merge');
const bundleAnalyzerReport = argv.report; // 根据命令参数是否含有 'report' 来决定是否生成报告
const APP_PATH = path.resolve(__dirname, '../src');
const webpackConfig = {
entry: {
app: './src/index.tsx',
vendor: ['react', 'react-dom'], // 不变的代码分包
},
output: {
filename: 'js/[name].bundle.js',
path: config.assetsRoot,
publicPath: config.publicPath,
},
module: {
rules: [
{
enforce: 'pre',
test: /\.tsx?$/,
exclude: /node_modules/,
include: [APP_PATH],
loader: 'eslint-loader',
options: {
emitWarning: true,
emitError: true,
fix: true, // 是否自动修复
},
},
{
oneOf: [
{
test: /\.(html)$/,
loader: 'html-loader',
},
{
test: /\.(j|t)sx?$/,
include: APP_PATH,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-react', // jsx支持
['@babel/preset-env', { useBuiltIns: 'usage', corejs: 2 }], // 按需使用polyfill
],
plugins: [
[
'@babel/plugin-proposal-class-properties',
{ loose: true },
], // class中的箭头函数中的this指向组件
],
cacheDirectory: true, // 加快编译速度
},
},
{
loader: 'awesome-typescript-loader',
},
],
},
{
test: /\.(less|css)$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: false, // 如果要启用css modules,改为true即可
},
},
{
loader: 'less-loader',
options: { javascriptEnabled: true },
},
],
},
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},
{
test: /\.(jpg|jpeg|bmp|png|webp|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024, // 小于这个大小的图片,会自动base64编码后插入到代码中
name: 'img/[name].[hash:8].[ext]',
outputPath: config.assetsDirectory,
publicPath: config.assetsRoot,
},
},
// 下面这个配置必须放在最后
{
exclude: [/\.(js|mjs|ts|tsx|less|css|jsx)$/, /\.html$/, /\.json$/],
loader: 'file-loader',
options: {
name: 'media/[path][name].[hash:8].[ext]',
outputPath: config.assetsDirectory,
publicPath: config.assetsRoot,
},
},
],
},
],
},
resolve: {
extensions: ['.js', '.json', '.jsx', '.ts', '.tsx'], // 自动判断后缀名,引入时可以不带后缀
alias: {
'@': path.resolve(__dirname, '../src/'), // 以 @ 表示src目录
},
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: config.indexPath,
showErrors: true,
}),
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
safe: true,
discardComments: { removeAll: true },
},
}),
],
splitChunks: {
chunks: 'all',
minChunks: 2,
maxInitialRequests: 5,
cacheGroups: {
// 提取公共模块
commons: {
chunks: 'all',
test: /[\\/]node_modules[\\/]/,
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
name: 'common',
},
},
},
},
};
if (bundleAnalyzerReport) {
webpackConfig.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: path.join(config.assetsRoot, './report.html'),
})
);
}
module.exports = webpackConfig;
需要安装对应的loader和plugin
TypeScript 配置
新建tsconfig.js
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"typeRoots": [
"src/types" // 指定 d.ts 文件的位置,根据具体情况修改
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "."
},
"include": ["src"],
"exclude": ["./node_modules"]
}
eslint + prettier
npm i -D eslint babel-eslint eslint-loader eslint-plugin-jsx-control-statements
npm i -D eslint-plugin-react @typescript-eslint/parser @typescript-eslint/eslint-plugin