@qse/edu-scripts 1.12.0

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +333 -0
  2. package/README.md +105 -0
  3. package/app.d.ts +68 -0
  4. package/docs/changelog.md +5 -0
  5. package/docs/deploy.md +53 -0
  6. package/docs/feat.md +74 -0
  7. package/docs/grayscale.md +31 -0
  8. package/docs/index.md +5 -0
  9. package/docs/mode.md +42 -0
  10. package/docs/override.md +165 -0
  11. package/docs/refactor-react-16.md +40 -0
  12. package/docs/refactor.md +139 -0
  13. package/jest.config.js +195 -0
  14. package/lib/asset/dll/libcommon3-manifest.json +181 -0
  15. package/lib/asset/template/edu-app-env.d.ts.tpl +15 -0
  16. package/lib/asset/template/edu-scripts.override.js.tpl +14 -0
  17. package/lib/asset/template/page/index.class.js.tpl +24 -0
  18. package/lib/asset/template/page/index.class.tsx.tpl +10 -0
  19. package/lib/asset/template/page/index.fc.js.tpl +16 -0
  20. package/lib/asset/template/page/index.fc.tsx.tpl +9 -0
  21. package/lib/asset/template/page/index.less.tpl +3 -0
  22. package/lib/asset/template/page/logic.js.tpl +4 -0
  23. package/lib/asset/template/page/route.js.tpl +12 -0
  24. package/lib/asset/template/tailwind.config.js.tpl +11 -0
  25. package/lib/asset/template/tsconfig.json.tpl +24 -0
  26. package/lib/auto-refactor.js +175 -0
  27. package/lib/build.js +87 -0
  28. package/lib/cli.js +63 -0
  29. package/lib/commit-dist.js +117 -0
  30. package/lib/config/babel.dependencies.js +56 -0
  31. package/lib/config/babel.js +82 -0
  32. package/lib/config/paths.js +44 -0
  33. package/lib/config/plugins/postcss-safe-area.js +22 -0
  34. package/lib/config/webpackConfig.js +384 -0
  35. package/lib/config/webpackDevServerConfig.js +47 -0
  36. package/lib/deploy.js +186 -0
  37. package/lib/generator.js +155 -0
  38. package/lib/index.d.ts +1 -0
  39. package/lib/index.js +13 -0
  40. package/lib/start.js +51 -0
  41. package/lib/utils/FileSizeReporter.js +131 -0
  42. package/lib/utils/appConfig.js +44 -0
  43. package/lib/utils/beforeStart.js +73 -0
  44. package/lib/utils/changeDeployVersion.js +125 -0
  45. package/lib/utils/defineConfig.d.ts +59 -0
  46. package/lib/utils/defineConfig.js +10 -0
  47. package/lib/utils/exec.js +13 -0
  48. package/lib/utils/getConfig.js +30 -0
  49. package/lib/utils/getOverride.js +33 -0
  50. package/package.json +102 -0
  51. package/src/asset/dll/libcommon3-manifest.json +181 -0
  52. package/src/asset/template/edu-app-env.d.ts.tpl +15 -0
  53. package/src/asset/template/edu-scripts.override.js.tpl +14 -0
  54. package/src/asset/template/page/index.class.js.tpl +24 -0
  55. package/src/asset/template/page/index.class.tsx.tpl +10 -0
  56. package/src/asset/template/page/index.fc.js.tpl +16 -0
  57. package/src/asset/template/page/index.fc.tsx.tpl +9 -0
  58. package/src/asset/template/page/index.less.tpl +3 -0
  59. package/src/asset/template/page/logic.js.tpl +4 -0
  60. package/src/asset/template/page/route.js.tpl +12 -0
  61. package/src/asset/template/tailwind.config.js.tpl +11 -0
  62. package/src/asset/template/tsconfig.json.tpl +24 -0
  63. package/src/auto-refactor.js +172 -0
  64. package/src/build.js +74 -0
  65. package/src/cli.js +91 -0
  66. package/src/commit-dist.js +103 -0
  67. package/src/config/babel.dependencies.js +65 -0
  68. package/src/config/babel.js +88 -0
  69. package/src/config/paths.js +37 -0
  70. package/src/config/plugins/postcss-safe-area.js +21 -0
  71. package/src/config/webpackConfig.js +410 -0
  72. package/src/config/webpackDevServerConfig.js +44 -0
  73. package/src/deploy.js +158 -0
  74. package/src/generator.js +138 -0
  75. package/src/index.ts +1 -0
  76. package/src/start.js +46 -0
  77. package/src/utils/FileSizeReporter.js +144 -0
  78. package/src/utils/appConfig.js +35 -0
  79. package/src/utils/beforeStart.js +66 -0
  80. package/src/utils/changeDeployVersion.js +115 -0
  81. package/src/utils/defineConfig.ts +63 -0
  82. package/src/utils/exec.js +7 -0
  83. package/src/utils/getConfig.js +26 -0
  84. package/src/utils/getOverride.js +32 -0
  85. package/tsconfig.json +31 -0
@@ -0,0 +1,172 @@
1
+ const fs = require('fs-extra')
2
+ const paths = require('./config/paths')
3
+ const path = require('path')
4
+ const chalk = require('chalk')
5
+ const pkg = require('../package.json')
6
+ const glob = require('globby')
7
+ const ora = require('ora')
8
+ const { prompt } = require('inquirer')
9
+ const open = require('open')
10
+
11
+ /**
12
+ * @param {string} msg
13
+ * @param {(spinner:ora.Ora) => void | Promise<void>} callback
14
+ */
15
+ async function step(msg, callback) {
16
+ const spinner = ora(msg).start()
17
+ try {
18
+ await callback(spinner)
19
+ spinner.succeed()
20
+ } catch (error) {
21
+ spinner.fail()
22
+ throw error
23
+ }
24
+ }
25
+
26
+ module.exports = async function autoRefactor() {
27
+ if (await fs.pathExists(paths.public)) {
28
+ console.log(chalk.green('已完成改造,不需要重复执行,如果运行报错请查看文档'))
29
+ console.log(`文档: ${chalk.underline(pkg.homepage)}`)
30
+ process.exit(0)
31
+ }
32
+
33
+ const appPkg = require(paths.package)
34
+ const answers = await prompt([
35
+ {
36
+ type: 'input',
37
+ name: 'name',
38
+ message: '请输入模块名称,要求唯一,不能与其他工程相同',
39
+ default: appPkg.name,
40
+ validate: (v) =>
41
+ /^[a-z][a-z0-9_-]+$/.test(v) ||
42
+ '请按格式输入 /^[a-z][a-z0-9_-]+$/ 只能使用小写字母、连字符、下划线',
43
+ },
44
+ {
45
+ type: 'input',
46
+ name: 'version',
47
+ message: '版本号',
48
+ default: '1.0.0',
49
+ validate: (v) =>
50
+ /^\d+\.\d+\.\d+$/.test(v) || '请按格式输入 /^\\d+\\.\\d+\\.\\d+$/ 例如: 1.0.0',
51
+ },
52
+ {
53
+ type: 'list',
54
+ name: 'mode',
55
+ message: '项目使用的哪种模式',
56
+ choices: [
57
+ { name: '教育子工程模式', value: '' },
58
+ { name: '教育主工程模式', value: 'main' },
59
+ { name: '独立模式', value: 'single' },
60
+ ],
61
+ },
62
+ {
63
+ type: 'checkbox',
64
+ name: 'deploy',
65
+ message: '项目需要部署到哪里',
66
+ when: (ans) => ans.mode !== 'single',
67
+ choices: [
68
+ { name: '校端', value: '-s' },
69
+ { name: '局端', value: '-b' },
70
+ { name: '公文端', value: '-d' },
71
+ ],
72
+ validate: (v) => (!!v && v.length > 0) || '必须选一个',
73
+ },
74
+ ])
75
+ appPkg.name = answers.name
76
+ appPkg.version = answers.version
77
+
78
+ await step('创建 public 文件夹', async () => {
79
+ await fs.mkdir(paths.public)
80
+ })
81
+
82
+ await step('移动 js 文件夹', async () => {
83
+ if (await fs.pathExists(path.resolve(paths.src, 'js'))) {
84
+ await fs.move(path.resolve(paths.src, 'js'), path.resolve(paths.public, 'js'))
85
+ }
86
+ })
87
+
88
+ await step('移动 html 文件', async () => {
89
+ const HTMLFiles = await glob('*.html', { cwd: paths.src })
90
+ for (const file of HTMLFiles) {
91
+ await fs.move(path.resolve(paths.src, file), path.resolve(paths.public, file))
92
+ }
93
+ })
94
+
95
+ await step('删除 dll 文件夹', async () => {
96
+ if (await fs.pathExists(path.resolve(paths.src, 'dll'))) {
97
+ await fs.remove(path.resolve(paths.src, 'dll'))
98
+ }
99
+ })
100
+
101
+ await step('删除没用的 babel 和 webpack 配置', async () => {
102
+ const deleteFiles = [
103
+ ...(await glob('{.,*}babel*')),
104
+ ...(await glob('*webpack*')),
105
+ ...(await glob('package-lock.json')),
106
+ paths.nodeModules,
107
+ paths.sshSftp,
108
+ ]
109
+ for (const filePath of deleteFiles) {
110
+ await fs.remove(filePath)
111
+ }
112
+ })
113
+
114
+ await step('设置项目模式', () => {
115
+ if (answers.mode) {
116
+ appPkg.edu = { mode: answers.mode }
117
+ }
118
+ })
119
+
120
+ await step('修改 package.json 的 scripts', () => {
121
+ const scripts = appPkg.scripts
122
+ scripts.start = 'edu-scripts start'
123
+ scripts.build = 'edu-scripts build'
124
+ scripts.analyze = 'edu-scripts build --analyze'
125
+ if (answers.mode !== 'single') {
126
+ scripts.deploy = `edu-scripts deploy ${answers.deploy.join(' ')}`
127
+ } else {
128
+ scripts.deploy = `edu-scripts deploy`
129
+ scripts['commit-dist'] = 'edu-scripts commit-dist --rm-local'
130
+ }
131
+ scripts['one-key-deploy'] = 'npm version patch'
132
+ scripts.postversion = 'npm run build && npm run deploy'
133
+ })
134
+
135
+ await step('删除 babel/webpack 相关依赖', (spinner) => {
136
+ const deleteRe =
137
+ /(babel|autoprefixer|webpack|loader|less|css|sass|hmr|ssh-sftp|regenerator-runtime|nowa)/i
138
+
139
+ const deletePkgs = {
140
+ dependencies: [],
141
+ devDependencies: [],
142
+ }
143
+ Object.entries(deletePkgs).forEach(([scope, pkgs]) => {
144
+ for (const key in appPkg[scope]) {
145
+ if (Object.hasOwnProperty.call(appPkg[scope], key)) {
146
+ if (deleteRe.test(key)) {
147
+ pkgs.push(key)
148
+ delete appPkg[scope][key]
149
+ }
150
+ }
151
+ }
152
+ })
153
+
154
+ spinner.clear()
155
+ console.log(`删除的pkgs\n${chalk.green(JSON.stringify(deletePkgs, null, 2))}\n`)
156
+ appPkg.devDependencies['@qse/edu-scripts'] = '^' + pkg.version
157
+ })
158
+
159
+ await fs.writeFile(paths.package, JSON.stringify(appPkg, null, 2), 'utf-8')
160
+
161
+ open(`${pkg.homepage}#/refactor`)
162
+
163
+ console.log(
164
+ chalk.green(`
165
+ 改造还未完成,剩余步骤请查看文档
166
+ ${pkg.homepage}#/refactor
167
+
168
+ 运行 npm i 安装依赖
169
+ 运行 edu-scripts start 启动服务
170
+ `)
171
+ )
172
+ }
package/src/build.js ADDED
@@ -0,0 +1,74 @@
1
+ process.env.NODE_ENV = 'production'
2
+ process.env.BABEL_ENV = 'production'
3
+ process.env.BROWSERSLIST = '>0.25%, not dead, not op_mini all'
4
+
5
+ const webpack = require('webpack')
6
+ const chalk = require('chalk')
7
+ const getConfig = require('./utils/getConfig')
8
+ const {
9
+ measureFileSizesBeforeBuild,
10
+ printFileSizesAfterBuild,
11
+ } = require('./utils/FileSizeReporter')
12
+ const paths = require('./config/paths')
13
+ const fs = require('fs-extra')
14
+ const appConfig = require('./utils/appConfig')
15
+ const WARN_AFTER_BUNDLE_GZIP_SIZE = appConfig.single ? 1024 * 1024 : 30 * 1024
16
+ const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024
17
+
18
+ module.exports = async function build(args) {
19
+ if (args.analyze) {
20
+ process.env.ANALYZE = '1'
21
+ }
22
+ if (args.outputHtml) {
23
+ process.env.OUTPUT_HTML = '1'
24
+ }
25
+
26
+ const previousSizeMap = await measureFileSizesBeforeBuild(paths.dist)
27
+ fs.emptyDirSync(paths.dist)
28
+
29
+ if (appConfig.single) {
30
+ fs.copySync(paths.public, paths.resolveApp('dist'))
31
+ }
32
+ if (appConfig.mainProject && fs.existsSync(paths.static)) {
33
+ fs.copySync(paths.static, paths.resolveApp('dist', 'static'))
34
+ }
35
+
36
+ webpack(getConfig(args), (error, stats) => {
37
+ if (error) {
38
+ console.log(chalk.red('编译失败'))
39
+ console.log(chalk.red(error.message || error))
40
+ console.log()
41
+ process.exit(1)
42
+ }
43
+
44
+ if (stats.compilation.errors.length) {
45
+ console.log(chalk.red('编译失败'))
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
+ process.exit(1)
52
+ }
53
+
54
+ console.log(stats.toString({ colors: true, preset: 'errors-warnings', timings: true }))
55
+ console.log()
56
+
57
+ console.log('gzip 后文件大小:\n')
58
+ printFileSizesAfterBuild(
59
+ stats,
60
+ previousSizeMap,
61
+ paths.dist,
62
+ WARN_AFTER_BUNDLE_GZIP_SIZE,
63
+ WARN_AFTER_CHUNK_GZIP_SIZE
64
+ )
65
+ console.log()
66
+
67
+ if (appConfig.single) {
68
+ console.log(`打包完成,可以使用 ${chalk.green('@qse/ssh-sftp')} 自动部署代码到 v1`)
69
+ } else {
70
+ console.log(`打包完成,可以运行 ${chalk.green('npx edu-scripts deploy')} 部署代码到 v1`)
71
+ }
72
+ console.log()
73
+ })
74
+ }
package/src/cli.js ADDED
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+ const pkg = require('../package.json')
3
+
4
+ // 检查运行条件
5
+ require('./utils/beforeStart')
6
+
7
+ // eslint-disable-next-line no-unused-expressions
8
+ require('yargs')
9
+ .usage(`教育工程化 webpack5 基础框架\n文档: ${pkg.homepage}`)
10
+ .command(
11
+ 'start',
12
+ '开发',
13
+ (yargs) =>
14
+ yargs
15
+ .option('port', { alias: 'p', desc: '指定端口' })
16
+ .option('open', { desc: '启动后打开页面' }),
17
+ (args) => require('./start')(args)
18
+ )
19
+ .command(
20
+ 'build',
21
+ '打包',
22
+ (yargs) =>
23
+ yargs
24
+ .option('analyze', {
25
+ alias: 'a',
26
+ desc: '分析代码',
27
+ default: false,
28
+ boolean: true,
29
+ })
30
+ .option('output-html', {
31
+ alias: 'o',
32
+ desc: '输出 html 文件',
33
+ default: false,
34
+ boolean: true,
35
+ }),
36
+ (args) => require('./build')(args)
37
+ )
38
+ .command(
39
+ 'deploy',
40
+ '自动部署 dist 到 v1 服务器',
41
+ (yargs) =>
42
+ yargs
43
+ .option('school', { alias: 's', desc: '上传到校端', default: false, boolean: true })
44
+ .option('bureau', { alias: 'b', desc: '上传到局端', default: false, boolean: true })
45
+ .option('documentshelves', {
46
+ alias: 'd',
47
+ desc: '上传到公文',
48
+ default: false,
49
+ boolean: true,
50
+ }),
51
+ (args) => require('./deploy')(args)
52
+ )
53
+ .command(['generator', 'g'], '自动生成代码', (yargs) =>
54
+ yargs
55
+ .command(
56
+ 'page',
57
+ '生成 page 模版, 默认根据环境生成 js/ts 与 less 文件',
58
+ (yargs) =>
59
+ yargs
60
+ .option('name', { desc: '模块名称', string: true })
61
+ .demandOption('name', '必须输入模块名称')
62
+ .option('ts', { alias: 't', desc: '生成 ts 文件', boolean: true, default: true })
63
+ .option('route', {
64
+ alias: 'r',
65
+ desc: '生成 index.js 路由文件',
66
+ boolean: true,
67
+ default: true,
68
+ })
69
+ .option('fc', { alias: 'f', desc: '生成 Function Component 文件', boolean: true }),
70
+ (args) => require('./generator').page(args)
71
+ )
72
+ .command('override', '创建 override 文件', {}, (args) =>
73
+ require('./generator').override(args)
74
+ )
75
+ .command('tailwind', '创建 tailwind 文件', {}, (args) =>
76
+ require('./generator').tailwind(args)
77
+ )
78
+ .command('ts', '创建 tsconfig 文件', {}, (args) => require('./generator').ts(args))
79
+ .showHelpOnFail(true)
80
+ .demandCommand(1, '')
81
+ )
82
+ .command('auto-refactor', '自动改造项目', {}, () => require('./auto-refactor')())
83
+ .command(
84
+ 'commit-dist',
85
+ '提交 dist 目录到 dist 分支',
86
+ (yargs) => yargs.option('rm-local', { desc: '提交完后删除本地 dist', type: 'boolean' }),
87
+ (args) => require('./commit-dist')(args)
88
+ )
89
+ .showHelpOnFail(true)
90
+ .demandCommand(1, '')
91
+ .alias({ v: 'version', h: 'help' }).argv
@@ -0,0 +1,103 @@
1
+ const chalk = require('chalk')
2
+ const paths = require('./config/paths')
3
+ const fs = require('fs-extra')
4
+ const exec = (cmd, opts) =>
5
+ require('child_process').execSync(cmd, { encoding: 'utf-8', stdio: 'pipe', ...opts })
6
+ const tmp = require('tmp')
7
+ const glob = require('globby')
8
+
9
+ function validateSVNRoot(root) {
10
+ const ls = exec(`svn ls ${root}`)
11
+ return ['trunk', 'branches'].every((s) => ls.includes(s))
12
+ }
13
+
14
+ function getWorkingCopyInfo() {
15
+ exec(`svn up`)
16
+ const url = exec(`svn info --show-item url`).trim()
17
+ const revision = exec(`svn info --show-item last-changed-revision`).trim()
18
+ const author = exec(`svn info --show-item last-changed-author`).trim()
19
+
20
+ let branch = 'trunk'
21
+ let root = url.replace(/\/trunk$/, '')
22
+ if (url.includes('/branches/')) {
23
+ branch = url.split('/').pop()
24
+ root = url.replace(/\/branches\/[^/]+$/, '')
25
+ }
26
+ let distBranchURL = root + '/branches/dist'
27
+ let distBranchDirURL = distBranchURL + '/' + branch
28
+ if (!validateSVNRoot(root)) {
29
+ console.log(chalk.red('SVN目录不符合规则,必须包含 trunk branches'))
30
+ process.exit(1)
31
+ }
32
+
33
+ return { url, branch, revision, author, distBranchURL, distBranchDirURL, root }
34
+ }
35
+
36
+ function copyDistToRepo(info) {
37
+ const tmpdir = tmp.dirSync().name
38
+
39
+ try {
40
+ exec(`svn ls ${info.distBranchDirURL} --depth empty`)
41
+ } catch (error) {
42
+ if (error.message.includes('non-existent')) {
43
+ exec(
44
+ `svn mkdir ${info.distBranchDirURL} --parents -m "[edu-scripts] create ${info.branch} dist"`
45
+ )
46
+ } else {
47
+ throw error
48
+ }
49
+ }
50
+ exec(`svn co ${info.distBranchDirURL} ${tmpdir}`)
51
+
52
+ let files = glob.sync('**/*', { cwd: tmpdir })
53
+ exec(`svn rm "${files.join('" "')}"`, { cwd: tmpdir })
54
+
55
+ fs.copySync(paths.dist, tmpdir)
56
+
57
+ files = glob.sync('**/*', { cwd: tmpdir })
58
+ exec(`svn add "${files.join('" "')}"`, { cwd: tmpdir })
59
+
60
+ const msg = `[edu-scripts] commit ${info.branch} dist #${info.revision} @${info.author}`
61
+ exec(`svn ci -m "${msg}"`, { cwd: tmpdir })
62
+
63
+ fs.removeSync(tmpdir)
64
+ }
65
+
66
+ /**
67
+ * svn commit dist folder to dish branches
68
+ *
69
+ * @param {Object} args
70
+ * @param {boolean} args.rmLocal
71
+ */
72
+ module.exports = async function commitDist(args) {
73
+ if (!fs.existsSync(paths.dist)) {
74
+ console.log(chalk.red('未找到 dist 文件夹,请先 edu-scpirts build'))
75
+ process.exit(1)
76
+ }
77
+
78
+ if (exec('svn st').trim().length) {
79
+ console.log(chalk.red('似乎存在未提交的代码,请提交后重试。运行 svn st 查看具体信息'))
80
+ process.exit(1)
81
+ }
82
+
83
+ const info = getWorkingCopyInfo()
84
+
85
+ console.log(
86
+ chalk.green(
87
+ [
88
+ `分支: ${info.branch}`,
89
+ `版本: ${info.revision}`,
90
+ `作者: ${info.author}`,
91
+ `地址: ${info.distBranchDirURL}`,
92
+ ].join('\n')
93
+ )
94
+ )
95
+
96
+ copyDistToRepo(info)
97
+
98
+ if (args.rmLocal) {
99
+ fs.removeSync(paths.dist)
100
+ }
101
+
102
+ console.log(chalk.green('提交完成'))
103
+ }
@@ -0,0 +1,65 @@
1
+ const getOverride = require('../utils/getOverride')
2
+
3
+ /**
4
+ * @typedef {Object} Opts
5
+ * @property {string} [modules]
6
+ *
7
+ * @param {Opts} [opts]
8
+ * @return {*}
9
+ */
10
+ module.exports = function getBabelConfig(opts = {}) {
11
+ const isDev = process.env.NODE_ENV === 'development'
12
+
13
+ let config = {
14
+ cacheDirectory: true,
15
+ cacheCompression: false,
16
+ babelrc: false,
17
+ configFile: false,
18
+ sourceType: 'unambiguous',
19
+ compact: false,
20
+ sourceMaps: isDev,
21
+ inputSourceMap: isDev,
22
+ presets: [
23
+ [
24
+ '@babel/preset-env',
25
+ {
26
+ modules: opts.modules,
27
+ useBuiltIns: 'entry',
28
+ corejs: 3,
29
+ // Exclude transforms that make all code slower
30
+ exclude: ['transform-typeof-symbol'],
31
+ },
32
+ ],
33
+ ].filter(Boolean),
34
+ plugins: [
35
+ [
36
+ '@babel/plugin-transform-runtime',
37
+ {
38
+ corejs: false,
39
+ helpers: true,
40
+ // By default, babel assumes babel/runtime version 7.0.0-beta.0,
41
+ // explicitly resolving to match the provided helper functions.
42
+ // https://github.com/babel/babel/issues/10261
43
+ version: require('@babel/runtime/package.json').version,
44
+ regenerator: true,
45
+ // // https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
46
+ // // We should turn this on once the lowest version of Node LTS
47
+ // // supports ES Modules.
48
+ // useESModules: true,
49
+ },
50
+ ],
51
+ [
52
+ 'import',
53
+ { libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false },
54
+ 'lodash',
55
+ ],
56
+ ].filter(Boolean),
57
+ }
58
+
59
+ const override = getOverride()
60
+ if (override.babel) {
61
+ config = override.babel(config, 'node_modules') || config
62
+ }
63
+
64
+ return config
65
+ }
@@ -0,0 +1,88 @@
1
+ const fs = require('fs')
2
+ const paths = require('./paths')
3
+ const appConfig = require('../utils/appConfig')
4
+ const getOverride = require('../utils/getOverride')
5
+ const hasJsxRuntime = (() => {
6
+ try {
7
+ require.resolve('react/jsx-runtime')
8
+ return true && appConfig.single
9
+ } catch (error) {
10
+ return false
11
+ }
12
+ })()
13
+
14
+ /**
15
+ * @typedef {Object} Opts
16
+ * @property {string} [modules]
17
+ *
18
+ * @param {Opts} [opts]
19
+ * @return {*}
20
+ */
21
+ module.exports = function getBabelConfig(opts = {}) {
22
+ const isTypeScriptEnabled = fs.existsSync(paths.tsconfig)
23
+ const isDev = process.env.NODE_ENV === 'development'
24
+
25
+ let config = {
26
+ cacheDirectory: true,
27
+ cacheCompression: false,
28
+ compact: !isDev,
29
+ babelrc: false,
30
+ configFile: false,
31
+ presets: [
32
+ [
33
+ '@babel/preset-env',
34
+ {
35
+ modules: opts.modules,
36
+ useBuiltIns: 'entry',
37
+ corejs: 3,
38
+ // Exclude transforms that make all code slower
39
+ exclude: ['transform-typeof-symbol'],
40
+ },
41
+ ],
42
+ [
43
+ '@babel/preset-react',
44
+ {
45
+ development: isDev,
46
+ runtime: hasJsxRuntime ? 'automatic' : 'classic',
47
+ useBuiltIns: !hasJsxRuntime,
48
+ },
49
+ ],
50
+ isTypeScriptEnabled && '@babel/preset-typescript',
51
+ ].filter(Boolean),
52
+ plugins: [
53
+ [
54
+ '@babel/plugin-transform-runtime',
55
+ {
56
+ corejs: false,
57
+ helpers: true,
58
+ // By default, babel assumes babel/runtime version 7.0.0-beta.0,
59
+ // explicitly resolving to match the provided helper functions.
60
+ // https://github.com/babel/babel/issues/10261
61
+ version: require('@babel/runtime/package.json').version,
62
+ regenerator: true,
63
+ // // https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
64
+ // // We should turn this on once the lowest version of Node LTS
65
+ // // supports ES Modules.
66
+ // useESModules: true,
67
+ },
68
+ ],
69
+ ['@babel/plugin-proposal-decorators', { legacy: true }],
70
+ ['@babel/plugin-proposal-class-properties', { loose: true }],
71
+ ['@babel/plugin-proposal-private-methods', { loose: true }],
72
+ ['@babel/plugin-proposal-private-property-in-object', { loose: true }],
73
+ [
74
+ 'import',
75
+ { libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false },
76
+ 'lodash',
77
+ ],
78
+ isDev && 'react-refresh/babel',
79
+ ].filter(Boolean),
80
+ }
81
+
82
+ const override = getOverride()
83
+ if (override.babel) {
84
+ config = override.babel(config, 'src') || config
85
+ }
86
+
87
+ return config
88
+ }
@@ -0,0 +1,37 @@
1
+ const path = require('path')
2
+ const fs = require('fs')
3
+ const glob = require('globby')
4
+
5
+ function resolveApp(...filePath) {
6
+ return path.resolve(process.cwd(), ...filePath)
7
+ }
8
+
9
+ function getExistPath(...paths) {
10
+ for (const path of paths) {
11
+ if (fs.existsSync(path)) {
12
+ return path
13
+ }
14
+ }
15
+ return paths[0]
16
+ }
17
+
18
+ const paths = {
19
+ resolveApp,
20
+ eduAppEnv: resolveApp('src', 'edu-app-env.d.ts'),
21
+ dist: resolveApp('dist'),
22
+ sshSftp: resolveApp('.sftprc.json'),
23
+ nodeModules: resolveApp('node_modules'),
24
+ tsconfig: resolveApp('tsconfig.json'),
25
+ jsconfig: resolveApp('jsconfig.json'),
26
+ package: resolveApp('package.json'),
27
+ tailwind: resolveApp('tailwind.config.js'),
28
+ indexJS: resolveApp('src', 'index.js'),
29
+ pages: resolveApp('src', 'pages'),
30
+ override: resolveApp('edu-scripts.override.js'),
31
+ indexHTML: glob.sync('./public/*.html', { absolute: true }),
32
+ src: resolveApp('src'),
33
+ public: resolveApp('public'),
34
+ static: resolveApp('public', 'static'),
35
+ theme: getExistPath(resolveApp('theme.json'), resolveApp('theme.js')),
36
+ }
37
+ module.exports = paths
@@ -0,0 +1,21 @@
1
+ const vars = [
2
+ 'safe-area-inset-top',
3
+ 'safe-area-inset-bottom',
4
+ 'safe-area-inset-left',
5
+ 'safe-area-inset-right',
6
+ ]
7
+
8
+ const expr = new RegExp(`env\\(\\s*(${vars.join('|')})\\s*,?\\s*([^)]+)?\\s*\\)`, 'g')
9
+
10
+ /** @type {import('postcss').PluginCreator} */
11
+ module.exports = () => {
12
+ return {
13
+ postcssPlugin: 'postcss-safe-area',
14
+ Declaration(decl) {
15
+ const fallback = decl.value.replace(expr, (match, param, defaultValue) => defaultValue || '0')
16
+ if (fallback !== decl.value) {
17
+ decl.cloneBefore({ value: fallback })
18
+ }
19
+ },
20
+ }
21
+ }