1.前言
前段时间突发一个想法,想尝试从零开始搭建一个React项目模板,发布到GitHub,再编写脚手架命令拉取模板以及编写脚本命令快速生成业务模块,然后再用这个模板结合之前的一套组件库,完成编译打包运行一些列操作,完善这个项目模板,再就是另外一个大事,用基于这个项目模板与组件库构建的项目,搭建自动化构建与自动化部署整个流程,将连载文章记录整个这个流程,以便后期回溯。
2.初始化项目
新建项目文件然后执行命令,-y
需要选择的地方默认是yes,执行完后会生成个package.json
文件
npm init -y
3.初始化typeScript配置
执行完命令后会生成tsconfig.json
文件,文件中会有全属性的配置与描述,在结合自己的需求配置使用
因tsconfig.json
篇幅太长只留了我的一些配置项
yarn typescript -g
tsc init
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
"target": "ES2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
4.配置react
4.1.安装依赖
yarn add react react-dom react-router-dom
yarn add @types/react @types/react-dom @types/react-router-dom --dev
4.2.新建html模板
新建public
目录下新建index.html
<!--public/index.html-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<link rel="icon" href="favicon" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
4.3.新建工程入口文件
新建src
目录下新建App.tsx
与index.tsx
// App.tsx
import React from 'react';
const App = () => {
return <div>buildDemo</div>;
};
export default App;
// index.tsx
import App from './App';
import ReactDom from 'react-dom';
import React from 'react';
ReactDom.render(<App />, document.querySelector('#root'));
5.配置webpack
5.1.安装webpack依赖(webpack版本5.x)
yarn add webpack webpack-cli webpack-merge html-webpack-plugin@next clean-webpack-plugin --dev
5.2.依赖包说明
html-webpack-plugin@next
wepack 5需要安装5.x版本的htmlplugin官网要求,具体运行处会有说明
clean-webpack-plugin
清楚打包目录的插件
5.3.新建webpack配置
新建config
文件存放webpack的配置文件:
webpack.config.base.js
webpack基本配置webpack.config.dev.js
webpack开发环境配置webpack.config.prod.js
webpack生产环境配置
// webpack.config.base.js
// 加上type在配置时会有提示
/**
* @type {import('webpack').Configuration}
*/
module.exports = {
entry: path.resolve(__dirname, '../src/index.tsx'),
output: {
filename: '[name].[hash].js',
path: path.resolve(__dirname, '../dist'),
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../publich/index.html'),
favicon: path.resolve(__dirname, '../publich/favicon.ico'),
hash: true,
}),
new CleanWebpackPlugin({
dry: false,
cleanOnceBeforeBuildPatterns: [path.resolve(__dirname, 'dist')],
}),
],
};
// webpack.config.dev.js
/**
* @type {import('webpack').WebpackOptionsNormalized}
*/
const devConfig = {
mode: 'development',
};
module.exports = webpackMerge.merge(baseConfig, devConfig);
// webpack.config.prod.js
/**
* @type {import('webpack').Configuration}
*/
const prodConfig = {
mode: 'production',
};
module.exports = webpackMerge(baseConfig, prodConfig);
6.配置babel
6.1.安装依赖(babel版本7.x)
yarn add babel-loader babel-plugin-import @babel/cli @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript --dev
6.2.依赖包说明
babel-loader
官网解释是文件预处理器,其实就是webpack处理静态文件的时候,需要各种loader来加载文件
babel-plugin-import
可以针对antd,antd-mobile,lodash等库进行按需加载
@babel/cli
内置的CLI命令行工具
@babel/core
需要调用babel的api进行转码,就要使用该模块
@babel/preset-env
是一个灵活的预设,你可以无需管理目标环境需要的语法转换或浏览器polyfill
,就可以使用最新的 JavaScript
@babel/preset-react
react预设
@babel/preset-typescript
typescript预设
6.3.创建babel.config.js文件
// type 编写时会有提示
/**
* @type {import('@babel/core').TransformOptions}
*/
module.exports = {
presets: [
[
'@babel/env',
{
useBuiltIns: 'usage',
corejs: 3,
},
],
'@babel/preset-react',
'@babel/preset-typescript',
],
};
webpack.config.base.js
中添加module配置
/**
* @type {import('webpack').Configuration}
*/
module.exports = {
...
module: {
rules: [
{
test: /.(js|ts)x?$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
},
},
],
},
};
7.配置开发服务器
yarn add webpack-dev-server --dev
webpack.config.dev.js
添加如下配置
/**
* @type {import('webpack-dev-server').Configuration}
*/
const devServer = {
port: 3000,
host: 'localhost',
contentBase: path.join(__dirname, '../publich'),
watchContentBase: true,
publicPath: '/',
compress: true,
historyApiFallback: true,
hot: true,
clientLogLevel: 'error',
// open: true,
watchOptions: {
ignored: /node_modules/,
},
};
/**
* @type {import('webpack').WebpackOptionsNormalized}
*/
const devConfig = {
mode: 'development',
devServer: devServer,
};
module.exports = webpackMerge.merge(baseConfig, devConfig);
package.json
中添加启动命令
"scripts": {
"start": "webpack serve --config ./config/webpack.config.dev.js"
},
8.启动
8.1.Error: Cannot find module 'webpack-cli/bin/config-yargs'
webpack-dev-server
启动过程中,如果webpack-cli
版本是4,则会报该错误
解决方案有两种:
- 修改命令
"start": "webpack serve --config ./config/webpack.config.dev.js"
- 降低
webpack-cli
的版本到3
再次启动抛出这个问题,排查是因为webpack.config.base.js
中resolve中extensions
未关联.js,.jsx
8.2.Error:Uglify SyntaxError: Unexpected token: punc ())
当使用UglifyJs
压缩时,出现这个错误,查阅相关资料是ES6
语法压缩问题
解决方案:把UglifyJs
移到webpack.optimization.minimizer
中
参考文献:https://stackoverflow.com/questions/42375468/uglify-syntaxerror-unexpected-token-punc
8.3.Error:Failed to decode param '/%PUBLIC_URL%/favicon.ico
出现这个问题的原因是我自己下载的依赖包没有关注版本
解决方案:
- 查阅
html-webpack-plugin
是webpack5
要使用这个版本的plugin"html-webpack-plugin": "^5.0.0-alpha.14",
- 还一种解决方案就是回退
webpack
到4然后用InterpolateHtmlPlugin
替换/%PUBLIC_URL%/
9.资料文献
https://juejin.cn/post/6844904192658636808
第一次记录写文章,文笔有限,多多包涵,ヾ(´ー`)ノ゛谢谢♪