@qse/edu-scripts 1.12.1 → 1.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # 更新日志
2
2
 
3
- ## 1.12.0 (2022-09-28)
3
+ ## 1.12.3 (2022-11-01)
4
+
5
+ - fix: 修复 commit-dist 错误
6
+
7
+ ## 1.12.2 (2022-09-29)
8
+
9
+ - feat: 校验 version 字段
10
+ - feat: 优化 cdn external 规则
11
+
12
+ ## 1.12.1 (2022-09-28)
4
13
 
5
14
  - chore: 修改组织名 @qse,发布公网
6
15
 
package/docs/faq.md ADDED
@@ -0,0 +1,99 @@
1
+ # 错误处理
2
+
3
+ ## moment 没有 external 掉
4
+
5
+ 全局搜索 `moment/locale/zh-cn`,把这些引入都删除掉即可
6
+
7
+ ## ueditor 提示 css 文件加载不到
8
+
9
+ 移动 `src/ueditor` 到 `public/ueditor`, 导入地址也修改下
10
+
11
+ 例子: `require('../../../public/ueditor/<something>')`
12
+
13
+ ## style 文件报错
14
+
15
+ ```js
16
+ import * as style from './index.less'
17
+ //=> 改成
18
+ import style from './index.less'
19
+ ```
20
+
21
+ ## 如果判断是缺少 `alias` 配置,使用 `npx edu-scripts g override` 生成配置文件,并且配置 `alias` 参数
22
+
23
+ ```js
24
+ const { defineConfig } = require('@qse/edu-scripts')
25
+ const path = require('path')
26
+
27
+ module.exports = defineConfig({
28
+ alias: {
29
+ pages: path.resolve('src/pages'),
30
+ },
31
+ })
32
+ ```
33
+
34
+ ## 动态导入 `import`,webpack4 以后 `import` 默认导出改成 `default`
35
+
36
+ ```js
37
+ // 以前写法
38
+ import('lodash/get').then((get) => {
39
+ get()
40
+ })
41
+
42
+ // 现在写法
43
+ import('lodash/get').then(({ default: get }) => {
44
+ get()
45
+ })
46
+ ```
47
+
48
+ ## `react` 组件热更新失效
49
+
50
+ 把上面的 `CDN` 加入到首页(index\*.html)中
51
+
52
+ 其中 `process.env.NODE_ENV` 那段代码是关键
53
+
54
+ 热更新需要 react16,请阅读[升级指南](/refactor-react-16)
55
+
56
+ ## 主文件过大,代码分割失效
57
+
58
+ 检查是否有 `require('./chunkfile').default` 这种写法,这会导致代码分割失效,直接打进 main 中
59
+
60
+ ```js
61
+ export default (callback) => {
62
+ require.ensure([], (require) => {
63
+ // 错误例子
64
+ callback(require('./chunkfile').default)
65
+
66
+ // 正确写法
67
+ const mod = require('./chunkfile')
68
+ callback(mod.default)
69
+ })
70
+ }
71
+ ```
72
+
73
+ 另外,webpack2 开始就不推荐使用 `require.ensure` 做代码分割了。现在可以使用 `import` 方式代码分割
74
+
75
+ ```js
76
+ export default (callback) => {
77
+ import(/* webpackChunkName: 'chunkfileName' */ './chunkfile').then((mod) => {
78
+ callback(mod.default)
79
+ })
80
+ }
81
+ ```
82
+
83
+ ## 子工程不能含有 public/static,现已自动删除
84
+
85
+ 子工程不能含有 static 是因为 新建子工程 如果拷贝了主工程代码,那 static 也复制了,打包部署 v1 后可能会覆盖主工程的 static。而且子工程本身就不应该有 static,不可以引入本地外部资源
86
+
87
+ ## qsbAntd is not defiend
88
+
89
+ 子工程项目如果出现这个错误,引入下面的静态资源
90
+
91
+ ```html
92
+ <!-- 确保已经引入 react moment antd -->
93
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/react-dev-preset.js"></script>
94
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/moment2.29.1.js"></script>
95
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/antd3.26.20.js"></script>
96
+
97
+ <!-- 引入 @qsb/antd -->
98
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/qsb-antd.min.js"></script>
99
+ ```
package/docs/feat.md CHANGED
@@ -33,7 +33,7 @@ export default () => (
33
33
 
34
34
  运行 `npx edu g page -h` 查看详细信息
35
35
 
36
- ## 支持[自定义配置](/override)
36
+ ## 支持[自定义配置](override.md)
37
37
 
38
38
  运行 `npx edu g override` 生成控制文件
39
39
 
@@ -58,10 +58,17 @@ export default () => (
58
58
 
59
59
  `antd3.26.20.js`
60
60
 
61
- - development external: `react`, `react-dom`, `moment`, `antd`
62
- - production external:
63
- - 教育模式 `react`, `react-dom`, `moment`, `antd`, `@qse/antd`, `@qse/scheme-render`
64
- - 独立模式 `react`, `react-dom`, `moment`, `antd`
61
+ - external: `react`, `react-dom`, `moment`, `antd`
62
+
63
+ 如果使用 `antd3.26.20.js` 将额外执行下列规则
64
+
65
+ `qsb-antd.min.js`
66
+
67
+ - external: `@qsb/antd`, `@qse/antd`
68
+
69
+ `qsb-scheme-render.min.js`
70
+
71
+ - external: `@qsb/scheme-render` `@qse/scheme-render`
65
72
 
66
73
  ## 支持 tailwindcss
67
74
 
@@ -72,3 +79,5 @@ export default () => (
72
79
  预处理很多样式[兼容性问题](https://preset-env.cssdb.org/features/#stage-2)
73
80
 
74
81
  为所有 `overflow: auto/scroll` 自动增加 `-webkit-overflow-scrolling: touch`
82
+
83
+ 为所有 `env(safe-area-inset-*)` 增加 fallback
package/docs/mode.md CHANGED
@@ -32,11 +32,11 @@ package.json 增加 mode 字段
32
32
 
33
33
  ## 共同
34
34
 
35
- 请查看[特性](/feat)
35
+ 请查看[特性](feat.md)
36
36
 
37
37
  ## 差异
38
38
 
39
39
  | 差异点 | 子工程 | 主工程 | 独立 |
40
40
  | ---------------------- | ---------------------------------------- | --------------------------------------------- | --------------------------------------------------------------------------------------- |
41
41
  | 打包 build | 不复制 `public`,不导出 `html` 文件 | 复制 `public/static` 文件夹,导出 `html` 文件 | 复制 `public` 文件夹,导出 `html` 文件,且输出的 `output.filename` 会添加 `contenthash` |
42
- | [部署 deploy](/deploy) | 只上传 `dist/js、dist/images` 两个文件夹 | 上传 `dist` | 同主工程 |
42
+ | [部署 deploy](deploy.md) | 只上传 `dist/js、dist/images` 两个文件夹 | 上传 `dist` | 同主工程 |
package/docs/refactor.md CHANGED
@@ -58,82 +58,4 @@
58
58
 
59
59
  ## 报错处理
60
60
 
61
- ## moment 没有 external 掉
62
-
63
- 全局搜索 `moment/locale/zh-cn`,把这些引入都删除掉即可
64
-
65
- ## ueditor 提示 css 文件加载不到
66
-
67
- 移动 `src/ueditor` 到 `public/ueditor`, 导入地址也修改下
68
-
69
- 例子: `require('../../../public/ueditor/<something>')`
70
-
71
- ### style 文件报错
72
-
73
- ```js
74
- import * as style from './index.less'
75
- //=> 改成
76
- import style from './index.less'
77
- ```
78
-
79
- ### 如果判断是缺少 `alias` 配置,使用 `npx edu-scripts g override` 生成配置文件,并且配置 `alias` 参数
80
-
81
- ```js
82
- const { defineConfig } = require('@qse/edu-scripts')
83
- const path = require('path')
84
-
85
- module.exports = defineConfig({
86
- alias: {
87
- pages: path.resolve('src/pages')
88
- }
89
- })
90
- ```
91
-
92
- ### 动态导入 `import`,webpack4 以后 `import` 默认导出改成 `default`
93
-
94
- ```js
95
- // 以前写法
96
- import('lodash/get').then(get=> {
97
- get()
98
- })
99
-
100
- // 现在写法
101
- import('lodash/get').then(({default: get})=> {
102
- get()
103
- })
104
- ```
105
-
106
- ### `react` 组件热更新失效
107
-
108
- 把上面的 `CDN` 加入到首页(index\*.html)中
109
-
110
- 其中 `process.env.NODE_ENV` 那段代码是关键
111
-
112
- 热更新需要 react16,请阅读[升级指南](/refactor-react-16)
113
-
114
- ### 主文件过大,代码分割失效
115
-
116
- 检查是否有 `require('./chunkfile').default` 这种写法,这会导致代码分割失效,直接打进 main 中
117
-
118
- ```js
119
- export default (callback) => {
120
- require.ensure([], (require) => {
121
- // 错误例子
122
- callback(require('./chunkfile').default)
123
-
124
- // 正确写法
125
- const mod = require('./chunkfile')
126
- callback(mod.default)
127
- })
128
- }
129
- ```
130
-
131
- 另外,webpack2 开始就不推荐使用 `require.ensure` 做代码分割了。现在可以使用 `import` 方式代码分割
132
-
133
- ```js
134
- export default (callback) => {
135
- import(/* webpackChunkName: 'chunkfileName' */ './chunkfile').then((mod) => {
136
- callback(mod.default)
137
- })
138
- }
139
- ```
61
+ 请看[错误处理](faq.md)
package/docs/static.md ADDED
@@ -0,0 +1,28 @@
1
+ # 静态资源
2
+
3
+ ## 开发环境使用的静态资源
4
+
5
+ ```html
6
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/react-dev-preset.js"></script>
7
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/moment2.29.1.js"></script>
8
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/antd3.26.20.js"></script>
9
+
10
+ <!-- 下方资源可能存在版本滞后 -->
11
+ <!-- @qsb/antd @1.5.4 -->
12
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/qsb-antd.min.js"></script>
13
+ <!-- @qsb/scheme-render @1.2.3 -->
14
+ <script src="//www.zhidianbao.cn:8088/qsxxwapdev/edu-scripts/qsb-scheme-render.min.js"></script>
15
+ ```
16
+
17
+ ## 生产环境使用的静态资源
18
+
19
+ ```html
20
+ <!-- 包含 react react-dom natty-fetch common-utils dll(refast react-keeper) -->
21
+ <script src="//static.qsepay.net/lib/react16.14_fastclick1.0.6_natty-storage2.0.2-fetch2.4.2_common31.js"></script>
22
+ <!-- 额外包含 axios @0.21.1 -->
23
+ <script src="//static.qsepay.net/lib/react16.14_fastclick1.0.6_natty-storage2.0.2-fetch2.4.2_axios0.21.1_common31.js"></script>
24
+
25
+ <!-- 包含 moment 与 moment-locale-zh-cn -->
26
+ <script src="//static.qsepay.net/lib/moment2.29.1.js"></script>
27
+ <script src="//static.qsepay.net/lib/antd3.26.20.js"></script>
28
+ ```
package/lib/build.js CHANGED
@@ -59,10 +59,6 @@ module.exports = async function build(args) {
59
59
  errors: true,
60
60
  colors: true
61
61
  }));
62
- } // Fail the build if running in a CI server
63
-
64
-
65
- if (error || stats.compilation.errors.length) {
66
62
  process.exit(1);
67
63
  }
68
64
 
@@ -14,8 +14,6 @@ const exec = (cmd, opts) => require('child_process').execSync(cmd, {
14
14
 
15
15
  const tmp = require('tmp');
16
16
 
17
- const glob = require('globby');
18
-
19
17
  function validateSVNRoot(root) {
20
18
  const ls = exec(`svn ls ${root}`);
21
19
  return ['trunk', 'branches'].every(s => ls.includes(s));
@@ -67,17 +65,15 @@ function copyDistToRepo(info) {
67
65
  }
68
66
 
69
67
  exec(`svn co ${info.distBranchDirURL} ${tmpdir}`);
70
- let files = glob.sync('**/*', {
71
- cwd: tmpdir
72
- });
73
- exec(`svn rm "${files.join('" "')}"`, {
74
- cwd: tmpdir
75
- });
68
+
69
+ try {
70
+ exec(`svn rm * --force -q`, {
71
+ cwd: tmpdir
72
+ });
73
+ } catch (error) {}
74
+
76
75
  fs.copySync(paths.dist, tmpdir);
77
- files = glob.sync('**/*', {
78
- cwd: tmpdir
79
- });
80
- exec(`svn add "${files.join('" "')}"`, {
76
+ exec(`svn add * --force --auto-props --parents --depth infinity -q`, {
81
77
  cwd: tmpdir
82
78
  });
83
79
  const msg = `[edu-scripts] commit ${info.branch} dist #${info.revision} @${info.author}`;
@@ -40,13 +40,17 @@ const qsbCDN = (() => {
40
40
  const isUseAxios = contents.some(content => /react16.14.*_axios0.21.1/.test(content));
41
41
  const isUseMoment = contents.some(content => content.includes('moment2.29.1.js'));
42
42
  const isUseAntd = contents.some(content => content.includes('antd3.26.20.js'));
43
- const isUse = isUseAntd || isUseCommon || isUseMoment || isUseAxios;
43
+ const isUseQsbAntd = contents.some(content => content.includes('qsb-antd.min.js'));
44
+ const isUseQsbSchemeRender = contents.some(content => content.includes('qsb-scheme-render.min.js'));
45
+ const isUse = isUseAntd || isUseCommon || isUseMoment || isUseAxios || isUseQsbAntd || isUseQsbSchemeRender;
44
46
  return {
45
47
  isUse,
46
48
  isUseAntd,
47
49
  isUseCommon,
48
50
  isUseMoment,
49
- isUseAxios
51
+ isUseAxios,
52
+ isUseQsbAntd,
53
+ isUseQsbSchemeRender
50
54
  };
51
55
  })();
52
56
  /**
@@ -137,18 +141,18 @@ module.exports = function getWebpackConfig(args, override) {
137
141
  axios: 'axios'
138
142
  }, qsbCDN.isUseMoment && {
139
143
  moment: 'moment'
140
- }, qsbCDN.isUseAntd && {
144
+ }, qsbCDN.isUseAntd && Object.assign({
141
145
  react: 'React',
142
146
  'react-dom': 'ReactDOM',
143
147
  moment: 'moment',
144
- antd: 'antd',
145
- ...(isProd && !appConfig.single ? {
146
- '@qse/antd': 'qsbAntd',
147
- '@qse/scheme-render': 'qsbSchemeRender',
148
- '@qsb/antd': 'qsbAntd',
149
- '@qsb/scheme-render': 'qsbSchemeRender'
150
- } : {})
151
- }, override.externals),
148
+ antd: 'antd'
149
+ }, qsbCDN.isUseQsbAntd && {
150
+ '@qse/antd': 'qsbAntd',
151
+ '@qsb/antd': 'qsbAntd'
152
+ }, qsbCDN.isUseQsbSchemeRender && {
153
+ '@qse/scheme-render': 'qsbSchemeRender',
154
+ '@qsb/scheme-render': 'qsbSchemeRender'
155
+ }), override.externals),
152
156
  resolve: {
153
157
  alias: {
154
158
  '@': paths.src,
@@ -271,7 +275,6 @@ module.exports = function getWebpackConfig(args, override) {
271
275
  }, {
272
276
  loader: 'url-loader',
273
277
  options: {
274
- name: `images/${assetPath}/[name].[hash:6].[ext]`,
275
278
  limit: imageInlineSizeLimit
276
279
  }
277
280
  }],
@@ -10,6 +10,8 @@ const pkg = require('../../package.json');
10
10
 
11
11
  const updateNotifier = require('update-notifier');
12
12
 
13
+ const semver = require('semver');
14
+
13
15
  const notifier = updateNotifier({
14
16
  pkg,
15
17
  shouldNotifyInNpmScript: true,
@@ -29,6 +31,11 @@ const appPkg = require(paths.package);
29
31
 
30
32
  const appConfig = require('./appConfig');
31
33
 
34
+ if (semver.valid(appPkg.version) === null) {
35
+ console.log(chalk.red(`package.version 不符合 semver 规范 https://docs.npmjs.com/about-semantic-versioning`));
36
+ process.exit(1);
37
+ }
38
+
32
39
  switch (appConfig.mode) {
33
40
  case 'main':
34
41
  console.log(chalk.bgMagenta('正在使用教育主工程模式'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qse/edu-scripts",
3
- "version": "1.12.1",
3
+ "version": "1.12.3",
4
4
  "author": "Kinoko",
5
5
  "license": "MIT",
6
6
  "description": "教育工程化基础框架",
@@ -73,6 +73,7 @@
73
73
  "react-refresh": "^0.13.0",
74
74
  "recursive-readdir": "^2.2.2",
75
75
  "rimraf": "^3.0.2",
76
+ "semver": "^7.3.7",
76
77
  "strip-ansi": "^6.0.1",
77
78
  "style-loader": "^3.3.1",
78
79
  "tailwindcss": "^3.1.2",
package/src/build.js CHANGED
@@ -44,10 +44,6 @@ module.exports = async function build(args) {
44
44
  if (stats.compilation.errors.length) {
45
45
  console.log(chalk.red('编译失败'))
46
46
  console.log(stats.toString({ all: false, errors: true, colors: true }))
47
- }
48
-
49
- // Fail the build if running in a CI server
50
- if (error || stats.compilation.errors.length) {
51
47
  process.exit(1)
52
48
  }
53
49
 
@@ -4,7 +4,6 @@ const fs = require('fs-extra')
4
4
  const exec = (cmd, opts) =>
5
5
  require('child_process').execSync(cmd, { encoding: 'utf-8', stdio: 'pipe', ...opts })
6
6
  const tmp = require('tmp')
7
- const glob = require('globby')
8
7
 
9
8
  function validateSVNRoot(root) {
10
9
  const ls = exec(`svn ls ${root}`)
@@ -49,13 +48,13 @@ function copyDistToRepo(info) {
49
48
  }
50
49
  exec(`svn co ${info.distBranchDirURL} ${tmpdir}`)
51
50
 
52
- let files = glob.sync('**/*', { cwd: tmpdir })
53
- exec(`svn rm "${files.join('" "')}"`, { cwd: tmpdir })
51
+ try {
52
+ exec(`svn rm * --force -q`, { cwd: tmpdir })
53
+ } catch (error) {}
54
54
 
55
55
  fs.copySync(paths.dist, tmpdir)
56
56
 
57
- files = glob.sync('**/*', { cwd: tmpdir })
58
- exec(`svn add "${files.join('" "')}"`, { cwd: tmpdir })
57
+ exec(`svn add * --force --auto-props --parents --depth infinity -q`, { cwd: tmpdir })
59
58
 
60
59
  const msg = `[edu-scripts] commit ${info.branch} dist #${info.revision} @${info.author}`
61
60
  exec(`svn ci -m "${msg}"`, { cwd: tmpdir })
@@ -30,9 +30,22 @@ const qsbCDN = (() => {
30
30
  const isUseAxios = contents.some((content) => /react16.14.*_axios0.21.1/.test(content))
31
31
  const isUseMoment = contents.some((content) => content.includes('moment2.29.1.js'))
32
32
  const isUseAntd = contents.some((content) => content.includes('antd3.26.20.js'))
33
+ const isUseQsbAntd = contents.some((content) => content.includes('qsb-antd.min.js'))
34
+ const isUseQsbSchemeRender = contents.some((content) =>
35
+ content.includes('qsb-scheme-render.min.js')
36
+ )
33
37
 
34
- const isUse = isUseAntd || isUseCommon || isUseMoment || isUseAxios
35
- return { isUse, isUseAntd, isUseCommon, isUseMoment, isUseAxios }
38
+ const isUse =
39
+ isUseAntd || isUseCommon || isUseMoment || isUseAxios || isUseQsbAntd || isUseQsbSchemeRender
40
+ return {
41
+ isUse,
42
+ isUseAntd,
43
+ isUseCommon,
44
+ isUseMoment,
45
+ isUseAxios,
46
+ isUseQsbAntd,
47
+ isUseQsbSchemeRender,
48
+ }
36
49
  })()
37
50
 
38
51
  /**
@@ -129,20 +142,23 @@ module.exports = function getWebpackConfig(args, override) {
129
142
  },
130
143
  qsbCDN.isUseAxios && { axios: 'axios' },
131
144
  qsbCDN.isUseMoment && { moment: 'moment' },
132
- qsbCDN.isUseAntd && {
133
- react: 'React',
134
- 'react-dom': 'ReactDOM',
135
- moment: 'moment',
136
- antd: 'antd',
137
- ...(isProd && !appConfig.single
138
- ? {
139
- '@qse/antd': 'qsbAntd',
140
- '@qse/scheme-render': 'qsbSchemeRender',
141
- '@qsb/antd': 'qsbAntd',
142
- '@qsb/scheme-render': 'qsbSchemeRender',
143
- }
144
- : {}),
145
- },
145
+ qsbCDN.isUseAntd &&
146
+ Object.assign(
147
+ {
148
+ react: 'React',
149
+ 'react-dom': 'ReactDOM',
150
+ moment: 'moment',
151
+ antd: 'antd',
152
+ },
153
+ qsbCDN.isUseQsbAntd && {
154
+ '@qse/antd': 'qsbAntd',
155
+ '@qsb/antd': 'qsbAntd',
156
+ },
157
+ qsbCDN.isUseQsbSchemeRender && {
158
+ '@qse/scheme-render': 'qsbSchemeRender',
159
+ '@qsb/scheme-render': 'qsbSchemeRender',
160
+ }
161
+ ),
146
162
  override.externals
147
163
  ),
148
164
  resolve: {
@@ -274,7 +290,6 @@ module.exports = function getWebpackConfig(args, override) {
274
290
  {
275
291
  loader: 'url-loader',
276
292
  options: {
277
- name: `images/${assetPath}/[name].[hash:6].[ext]`,
278
293
  limit: imageInlineSizeLimit,
279
294
  },
280
295
  },
@@ -3,6 +3,7 @@ const paths = require('../config/paths')
3
3
  const chalk = require('chalk')
4
4
  const pkg = require('../../package.json')
5
5
  const updateNotifier = require('update-notifier')
6
+ const semver = require('semver')
6
7
 
7
8
  const notifier = updateNotifier({
8
9
  pkg,
@@ -27,6 +28,14 @@ if (notifier.update && ['minor', 'major'].includes(notifier.update.type)) {
27
28
 
28
29
  const appPkg = require(paths.package)
29
30
  const appConfig = require('./appConfig')
31
+
32
+ if (semver.valid(appPkg.version) === null) {
33
+ console.log(
34
+ chalk.red(`package.version 不符合 semver 规范 https://docs.npmjs.com/about-semantic-versioning`)
35
+ )
36
+ process.exit(1)
37
+ }
38
+
30
39
  switch (appConfig.mode) {
31
40
  case 'main':
32
41
  console.log(chalk.bgMagenta('正在使用教育主工程模式'))