Webpack5.x + Babel7.x + React17.0.2 + Antd4.x平台搭建V2.0
Arena
Webpack5.x + Babel7.x + React17.0.2 + Antd4.x平台搭建V2.0 -> 本文代码地址
项目初始化
通过npm init
初始化项目,一路yes,生成package.json文件
安装webpack5
npm i -g webpack webpack-cli
npm i -D webpack webpack-cli
安装babel7
babel是js兼容性处理工具,负责把es6+代码转换为es5代码供浏览器识别
- 全局安装
@babel/cli
@babel/core
,安装后可检查babel版本
npm i -g @babel/cli @babel/core
babel -V //7.14.5 (@babel/core 7.14.6)
- 项目安装
@babel/core
@babel/preset-env
@babel/preset-react
babel-loader
,同时安装@babel/polyfill
npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader @babel/plugin-proposal-class-properties core-js
各模块功能简介:
- @babel/core: 用来转码的核心模块,默认只转换新语法,不转换新API(如Iterator、Generator、Set、Map、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法)
- babel-loader: webpack用babel处理js/jsx文件的loader,用来转换代码
- @babel/preset-env: 设置babel-loader做基本兼容性处理,不能处理高级API
- @babel/preset-react: 设置对react语法的转换
- @babel/plugin-proposal-class-properties: 设置支持类的属性声明
- core-js: 让高级API生效的库
安装webpack各种常用加载器、插件和工具
npm i -D clean-webpack-plugin html-webpack-plugin
npm i -D file-loader url-loader style-loader css-loader
npm i -D webpack-dev-server webpack-merge
各模块功能简介:
- clean-webpack-plugin: 每次build前清理dist目录
- html-webpack-plugin: 用指定html模板构建入口html文件
- file-loader: 处理可支持的资源文件类型(如图片、字体等资源),打包到dist目录中
- url-loader:功能同file-loader,区别是增加limit选项,小于limit大小的图片会被转码为base64直接插入到js文件中
- css-loader: 将css文件变成样式字符串,以commonjs模块形式加载到js中
- style-loader: 创建style标签,将css-loader生成的样式字符串放到标签里,插入到html的head中
- webpack-dev-server: 开发模式的热更新,注意3.x版本使用方法跟2.x不同
- webpack-merge: 合并webpack配置文件的工具
查看本地webpack各模块版本
npx webpack --version
// webpack 5.42.0
// webpack-cli 4.7.2
// webpack-dev-server 3.11.2
安装React17.0.2依赖
npm i -S react react-dom react-router-dom
安装eslint
-
本地安装eslint
npm i -D eslint
-
初始化并生成配置文件
.eslintrc.js
,各初始化参数可以先随便选,后面再做修改./node_modules/.bin/eslint --init
-
安装对babel和react的支持
npm i -D babel-eslint eslint-plugin-react eslint-plugin-react-hooks
-
引入Airbnb规则
npm i -D eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y
-
修改.eslintrc.js配置文件
module.exports = { "env": { "browser": true, "es2020": true, "node": true }, "extends": [ "airbnb", ], "globals": { "Atomics": "readonly", "SharedArrayBuffer": "readonly", "Babel": true, "React": true }, "parser": "babel-eslint", "parserOptions": { "ecmaFeatures": { "jsx": true }, "ecmaVersion": 11, "sourceType": "module" }, "plugins": [ "react" ], "rules": { "linebreak-style": [ "off", "unix" ], "quotes": [ "error", "single" ], "semi": [ "error", "always" ], // 禁止缩进错误 "indent": 0, // 关闭不允许使用 no-tabs "no-tabs": "off", "no-console": 1, // 设置不冲突 underscore 库 "no-underscore-dangle": 0, // 箭头函数直接返回的时候不需要 大括号 {} "arrow-body-style": [2, "as-needed"], "no-alert": "error", // 最大长度关闭 "max-len": 0, // 设置是否可以重新改变参数的值 "no-param-reassign": 0, // 允许使用 for in "no-restricted-syntax": 0, "guard-for-in": 0, // 不需要每次都有返回 "consistent-return": 0, // 允许使用 arguments "prefer-rest-params": 0, // 允许返回 await "no-return-await": 0, // 不必在使用前定义 函数 "no-use-before-define": 0, // 允许代码后面空白 "no-trailing-spaces": 0, // 关闭大括号内的换行符要求 "object-curly-newline": 0, // 有一些 event 的时候,不需要 role 属性,不需要其他解释 "jsx-a11y/no-static-element-interactions": 0, "jsx-a11y/click-events-have-key-events": 0, // 类成员之间空行问题 "lines-between-class-members": 0, // 不区分是否在 despendencies "import/no-extraneous-dependencies": 0, // 引用时候根据根目录基础 "import/no-unresolved": 0, // 关闭解构赋值报错 "react/destructuring-assignment": 0, // 允许在 .js 和 .jsx 文件中使用 jsx "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], // 不区分是否是 无状态组件 "react/prefer-stateless-function": 0, // prop-types忽略一些属性 "react/prop-types": [1, { ignore: ["children", "history", "form"], }], // 关闭禁止prop-types类型 "react/forbid-prop-types": 0, // 关闭default-props检查 "react/require-default-props": 0, // 关闭禁止属性使用...运算符 "react/jsx-props-no-spreading": 0, // 关闭括号合拢标记换行报错 "react/jsx-closing-bracket-location": 0, // 关闭state初始方式限制 "react/state-in-constructor": 0, // 关闭react一行表达式数量限制 "react/jsx-one-expression-per-line": 0, } };
新建webpack配置文件
-
在根目录下新建config目录,新建如下三个配置文件:
- webpack.base.conf.js为公用配置
- webpack.dev.conf.js为开发环境配置,继承自webpack.base.conf.js
- webpack.prod.conf.js为生产环境配置,继承自webpack.base.conf.js
-
修改webpack.base.conf.js文件
'use strict' const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { // 入口起点 entry: { app: './src/index.js', }, // 输出 output: { path: path.resolve(__dirname, '../dist'), filename: '[name].js', }, // import引入这些类型文件时这些扩展名可以省略 resolve: { extensions: ['.ts', '.tsx', '.js', '.json', '.jsx'], }, // loader module: { rules: [ { test: /\.js|jsx$/, exclude: /node_modules/, // 屏蔽不需要处理的文件(文件夹) loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', // 处理ES6新语法兼容 { useBuiltIns: 'usage', corejs: 3, // core-js处理ES6新API兼容 }, ], '@babel/preset-react', // 处理React兼容性 ], plugins: [ ['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }], // 处理antd样式 '@babel/plugin-proposal-class-properties', // 处理类属性定义 ], }, }, { test: /\.css$/, use: [ // 'style-loader', MiniCssExtractPlugin.loader, 'css-loader', ], }, ], }, // 插件 plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: './src/index.html', // favicon: './static/favicon.ico', inject: 'body', }), new MiniCssExtractPlugin({ filename: 'css/built.css', }), ], };
-
修改webpack.dev.conf.js文件
//webpack.dev.conf.js const { merge } = require('webpack-merge'); const webpack = require('webpack'); const baseWebpackConfig = require('./webpack.base.conf'); module.exports = merge(baseWebpackConfig, { // 模式 mode: 'development', // 调试工具 devtool: 'inline-source-map', // 开发服务器 devServer: { contentBase: false, // 默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录 historyApiFallback: true, // 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html compress: true, // 启用gzip压缩 inline: true, // 设置为true,当源文件改变时会自动刷新页面 hot: true, // 模块热更新,取决于HotModuleReplacementPlugin host: '127.0.0.1', // 设置默认监听域名,如果省略,默认为“localhost” port: 8703, // 设置默认监听端口,如果省略,默认为“8080”, open: true, // 默认打开浏览器进入页面 }, // 插件 plugins: [ new webpack.HotModuleReplacementPlugin(), ], optimization: { nodeEnv: 'development', moduleIds: 'named', }, target: 'web', });
-
修改webpack.prod.conf.js文件
//webpack.prod.conf.js 'use strict' const { merge } = require('webpack-merge'); const path = require('path'); const webpack = require('webpack'); // 注意:此插件3.0版本引用时候需要大括号,2.0版本则不用 const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const baseWebpackConfig = require('./webpack.base.conf'); module.exports = merge(baseWebpackConfig, { // 模式 mode: 'production', // 调试工具 devtool: 'source-map', // 输出 output: { path: path.resolve(__dirname, '../dist'), filename: 'js/[name].[chunkhash].js', }, // 插件 plugins: [ new CleanWebpackPlugin(), new webpack.ids.HashedModuleIdsPlugin(), new BundleAnalyzerPlugin(), ], // 代码分离相关 optimization: { nodeEnv: 'production', runtimeChunk: { name: 'manifest', }, splitChunks: { minSize: 30000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, name: false, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendor', chunks: 'initial', }, }, }, }, });
-
修改package.json的scripts部分, 注意devServer的启动命令跟老版本的区别
"scripts": { "dev": "npx webpack serve --progress --config config/webpack.dev.conf.js", "start": "npm run dev", "build": "npx webpack --progress --config config/webpack.prod.conf.js" },
安装Ant Design
-
安装antd和babel-plugin-import工具实现按需加载
npm i -S antd babel-plugin-import
-
修改webpack.base.conf.js配置文件js的loader部分
{ test: /\.js|jsx$/, exclude: /node_modules/,// 屏蔽不需要处理的文件(文件夹)(可选) loader: 'babel-loader', options:{ presets: [ [ '@babel/preset-env', // 处理ES6新语法兼容 { useBuiltIns: 'usage', corejs: 3, // core-js处理ES6新API兼容 }, ], '@babel/preset-react' // 处理React兼容性 ], plugins: [ "@babel/plugin-proposal-class-properties", // 处理类属性定义 ['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }], // 处理antd样式 ] } },
安装styled-components
-
安装styled-components
npm i -S styled-components
demo代码
-
在src目录下新建index.html和index.js文件
Document
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Button } from 'antd';
import styled from 'styled-components';
const Sdiv = styled.div`
background-color: pink;
`;
const App = () => (
Hello React
)
ReactDOM.render( , document.getElementById('app'));
-
运行
npm start //启动devServer npm run build //打包
css文件单独打包
-
如果不想把css文件跟js文件打到一起,可以利用mini-css-extract-plugin插件将css文件独立出来
npm i -D mini-css-extract-plugin
-
修改webpack.base.conf.js文件中css处理模块的代码
// 开头引入插件 const MiniCssExtractPlugin = require('mini-css-extract-plugin'); …… // module - rules - css-loader部分修改:用MiniCssExtractPlugin.loader替换style-loader { test: /\.css$/, use: [ // 'style-loader', MiniCssExtractPlugin.loader, 'css-loader' ], } …… // plugins增加一个插件 new MiniCssExtractPlugin({ filename: 'css/built.css' //打包位置 })
查看打包文件大小和构成的可视化工具
-
安装BundleAnalyzerPlugin
npm i -D webpack-bundle-analyzer
-
在webpack.prod.conf.js文件中修改配置
// 开头引入插件 const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); …… // plugins中添加插件 new BundleAnalyzerPlugin(),