Skip to content

Commit 2d2399e

Browse files
committed
first commit
0 parents  commit 2d2399e

17 files changed

Lines changed: 704 additions & 0 deletions

File tree

.gitignore

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
!.mvn/wrapper/maven-wrapper.jar
3+
4+
### Eclipse template
5+
*.pydevproject
6+
.metadata
7+
.gradle
8+
bin/
9+
tmp/
10+
*.tmp
11+
*.bak
12+
*.swp
13+
*~.nib
14+
local.properties
15+
.settings/
16+
.loadpath
17+
18+
# Eclipse Core
19+
.project
20+
21+
# External tool builders
22+
.externalToolBuilders/
23+
24+
# Locally stored "Eclipse launch configurations"
25+
*.launch
26+
27+
# CDT-specific
28+
.cproject
29+
30+
# JDT-specific (Eclipse Java Development Tools)
31+
.classpath
32+
33+
# Java annotation processor (APT)
34+
.factorypath
35+
36+
# PDT-specific
37+
.buildpath
38+
39+
# sbteclipse plugin
40+
.target
41+
42+
# TeXlipse plugin
43+
.texlipse
44+
45+
46+
### OSX template
47+
.DS_Store
48+
.AppleDouble
49+
.LSOverride
50+
51+
# Icon must end with two \r
52+
Icon
53+
54+
# Thumbnails
55+
._*
56+
57+
# Files that might appear in the root of a volume
58+
.DocumentRevisions-V100
59+
.fseventsd
60+
.Spotlight-V100
61+
.TemporaryItems
62+
.Trashes
63+
.VolumeIcon.icns
64+
65+
# Directories potentially created on remote AFP share
66+
.AppleDB
67+
.AppleDesktop
68+
Network Trash Folder
69+
Temporary Items
70+
.apdisk
71+
72+
73+
### Java template
74+
*.class
75+
76+
# Mobile Tools for Java (J2ME)
77+
.mtj.tmp/
78+
79+
# Package Files #
80+
*.jar
81+
*.war
82+
*.ear
83+
84+
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
85+
hs_err_pid*
86+
87+
88+
### Maven template
89+
target/
90+
pom.xml.tag
91+
pom.xml.releaseBackup
92+
pom.xml.versionsBackup
93+
pom.xml.next
94+
release.properties
95+
dependency-reduced-pom.xml
96+
buildNumber.properties
97+
.mvn/timing.properties
98+
99+
100+
### JetBrains template
101+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
102+
103+
*.iml
104+
105+
## Directory-based project format:
106+
.idea/
107+
# if you remove the above rule, at least ignore the following:
108+
109+
# User-specific stuff:
110+
# .idea/workspace.xml
111+
# .idea/tasks.xml
112+
# .idea/dictionaries
113+
114+
# Sensitive or high-churn files:
115+
# .idea/dataSources.ids
116+
# .idea/dataSources.xml
117+
# .idea/sqlDataSources.xml
118+
# .idea/dynamic.xml
119+
# .idea/uiDesigner.xml
120+
121+
# Gradle:
122+
# .idea/gradle.xml
123+
# .idea/libraries
124+
125+
# Mongo Explorer plugin:
126+
# .idea/mongoSettings.xml
127+
128+
## File-based project format:
129+
*.ipr
130+
*.iws
131+
132+
## Plugin-specific files:
133+
134+
# IntelliJ
135+
/out/
136+
.idea
137+
138+
# mpeltonen/sbt-idea plugin
139+
.idea_modules/
140+
141+
# JIRA plugin
142+
atlassian-ide-plugin.xml
143+
144+
# Crashlytics plugin (for Android Studio and IntelliJ)
145+
com_crashlytics_export_strings.xml
146+
crashlytics.properties
147+
crashlytics-build.properties
148+
149+
logs/
150+
151+
document.html
152+
swagger.json
153+
154+
155+
# dependencies
156+
node_modules
157+
.pnp
158+
.pnp.js
159+
160+
# production
161+
build
162+
163+
# misc
164+
.DS_Store
165+
.env.local
166+
.env.development.local
167+
.env.test.local
168+
.env.production.local
169+
170+
npm-debug.log*
171+
yarn-debug.log*
172+
yarn-error.log*
173+
174+
yarn.lock
175+
package-lock.json
176+
react-app-env.d.ts

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#### React + TypeScript + Router + Mobx + Antd + 多页面开发模板(免npm run eject)
2+
3+
### 1.基础模板: create-react-app
4+
5+
### 2.开发模式
6+
* src/setupProxy.js配置代理
7+
* 执行
8+
npm run start
9+
10+
yarn run start
11+
12+
打开:http://localhost:3000/ 默认index页面
13+
打开:http://localhost:3000/admin.html 打开admin页面
14+
15+
### 3.构建线上文件
16+
* 执行
17+
npm run build
18+
19+
yarn run build
20+
21+
build目录下将生成两个html文件: index.html和admin.html 分别对应连个entry入口
22+
23+
### 4.构建过程
24+
多页面开发参考文章:https://segmentfault.com/a/1190000017858725
25+
需要改动的地方:
26+
require.resolve('./node_modules/react-scripts/config/polyfills.js')
27+
改成
28+
require.resolve('react-app-polyfill/stable')
29+
30+
Mobx支持及静态类型支持参考:src/index/components/header/Header.tsx
31+
32+
Router支持参考:src/index/components/header/Header.tsx

config-overrides.js

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
const { paths } = require('react-app-rewired');
2+
const HtmlWebpackPlugin = require('html-webpack-plugin');
3+
const path = require('path');
4+
const fs = require('fs');
5+
const globby = require('globby');
6+
const appDirectory = fs.realpathSync(process.cwd());
7+
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
8+
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
9+
10+
module.exports = function override(config, env) {
11+
// 入口文件路径
12+
// const entriesPath = globby.sync([resolveApp('src') + '/*/index.js']);
13+
const entriesPath = globby.sync([resolveApp('src') + '/*/index.tsx'], {cwd: process.cwd()});
14+
paths.entriesPath = entriesPath;
15+
16+
// 获取指定路径下的入口文件
17+
function getEntries(){
18+
const entries = {};
19+
const files = paths.entriesPath;
20+
files.forEach(filePath => {
21+
let tmp = filePath.split('/');
22+
let name = tmp[tmp.length - 2];
23+
if(env === 'production'){
24+
entries[name] = [
25+
require.resolve('react-app-polyfill/stable'),
26+
filePath,
27+
];
28+
} else {
29+
entries[name] = [
30+
require.resolve('react-app-polyfill/stable'),
31+
require.resolve('react-dev-utils/webpackHotDevClient'),
32+
filePath,
33+
];
34+
}
35+
});
36+
return entries;
37+
}
38+
39+
// 入口文件对象
40+
const entries = getEntries();
41+
42+
// 配置 HtmlWebpackPlugin 插件, 指定入口文件生成对应的 html 文件
43+
let htmlPlugin;
44+
if(env === 'production'){
45+
htmlPlugin = Object.keys(entries).map(item => {
46+
return new HtmlWebpackPlugin({
47+
inject: true,
48+
template: paths.appHtml,
49+
filename: item + '.html',
50+
chunks: [item],
51+
minify: {
52+
removeComments: true,
53+
collapseWhitespace: true,
54+
removeRedundantAttributes: true,
55+
useShortDoctype: true,
56+
removeEmptyAttributes: true,
57+
removeStyleLinkTypeAttributes: true,
58+
keepClosingSlash: true,
59+
minifyJS: true,
60+
minifyCSS: true,
61+
minifyURLs: true,
62+
},
63+
});
64+
});
65+
} else {
66+
htmlPlugin = Object.keys(entries).map(item => {
67+
return new HtmlWebpackPlugin({
68+
inject: true,
69+
template: paths.appHtml,
70+
filename: item + '.html',
71+
chunks: [item],
72+
});
73+
});
74+
}
75+
76+
if (env === 'production') {
77+
for (let i = 0; i < config.plugins.length; i++) {
78+
let item = config.plugins[i];
79+
80+
// 更改输出的样式文件名
81+
if (item.constructor.toString().indexOf('class MiniCssExtractPlugin') > -1) {
82+
item.options.filename = 'static/css/[name].[chunkhash:8].css';
83+
item.options.chunkFilename = 'static/css/[name].chunk.[chunkhash:8].css';
84+
}
85+
86+
// SWPrecacheWebpackPlugin: 使用 service workers 缓存项目依赖
87+
if(item.constructor.toString().indexOf('function GenerateSW') > -1){
88+
// 更改输出的文件名
89+
item.config.precacheManifestFilename = 'precache-manifest.[chunkhash:8].js';
90+
}
91+
}
92+
93+
// 更改生产模式输出的文件名
94+
config.output.filename = 'static/js/[name].[chunkhash:8].js';
95+
config.output.chunkFilename = 'static/js/[name].chunk.[chunkhash:8].js';
96+
97+
} else {
98+
// 更改开发模式输出的文件名
99+
config.output.filename = 'static/js/[name].js';
100+
config.output.chunkFilename = 'static/js/[name].chunk.js';
101+
}
102+
103+
// 修改入口
104+
config.entry = entries;
105+
106+
// 修改 HtmlWebpackPlugin 插件
107+
for (let i = 0; i < config.plugins.length; i++) {
108+
let item = config.plugins[i];
109+
if (item.constructor.toString().indexOf('class HtmlWebpackPlugin') > -1) {
110+
config.plugins.splice(i, 1);
111+
}
112+
}
113+
114+
config.plugins.push(...htmlPlugin);
115+
116+
// 分析打包内容
117+
// config.plugins.push(new BundleAnalyzerPlugin());
118+
119+
// 设置别名路径
120+
config.resolve.alias = {
121+
...config.resolve.alias,
122+
'@src': paths.appSrc, // 在使用中有些 Eslint 规则会报错, 禁用这部分代码的 Eslint 检测即可
123+
};
124+
125+
// 修改代码拆分规则,详见 webpack 文档:https://webpack.js.org/plugins/split-chunks-plugin/#optimization-splitchunks
126+
config.optimization = {
127+
splitChunks: {
128+
// 将所有入口点共同使用到的、次数超过 2 次的模块,创建为一个名为 commons 的代码块
129+
// 这种配置方式可能会增大初始的捆绑包,比如有些公共模块在首页其实并未用到,但也会打包进来,会降低首页的加载性能
130+
// 建议将非必需模块使用 import() 的方式动态加载,提升页面的加载速度
131+
// cacheGroups: {
132+
// commons: {
133+
// name: 'commons',
134+
// chunks: 'initial',
135+
// minChunks: 2
136+
// }
137+
// }
138+
139+
// 将所有使用到的 node_modules 中的模块包打包为 vendors 代码块。(不推荐)
140+
// 这种方式可能会产生一个包含所有外部依赖包的较大代码块,建议只包含核心框架和工具函数代码,其他依赖项动态加载
141+
// cacheGroups: {
142+
// commons: {
143+
// test: /[\\/]node_modules[\\/]/,
144+
// name: 'vendors',
145+
// chunks: 'all'
146+
// }
147+
// }
148+
149+
cacheGroups: {
150+
// 通过正则匹配,将 react react-dom echarts-for-react 等公共模块拆分为 vendor
151+
// 这里仅作为示例,具体需要拆分哪些模块需要根据项目需要进行配置
152+
// 可以通过 BundleAnalyzerPlugin 帮助确定拆分哪些模块包
153+
vendor: {
154+
test: /[\\/]node_modules[\\/](react|react-dom|echarts-for-react)[\\/]/,
155+
name: 'vendor',
156+
chunks: 'all', // all, async, and initial
157+
},
158+
159+
// 将 css|less 文件合并成一个文件, mini-css-extract-plugin 的用法请参见文档:https://www.npmjs.com/package/mini-css-extract-plugin
160+
// MiniCssExtractPlugin 会将动态 import 引入的模块的样式文件也分离出去,将这些样式文件合并成一个文件可以提高渲染速度
161+
// 其实如果可以不使用 mini-css-extract-plugin 这个插件,即不分离样式文件,可能更适合本方案,但是我没有找到方法去除这个插件
162+
styles: {
163+
name: 'styles',
164+
test: /\.css|less$/,
165+
chunks: 'all', // merge all the css chunk to one file
166+
enforce: true
167+
}
168+
},
169+
},
170+
};
171+
172+
return config;
173+
};

0 commit comments

Comments
 (0)