@modern-js/module-tools 1.0.0-alpha.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.
Files changed (187) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +32 -0
  4. package/bin/modern.js +3 -0
  5. package/dist/js/modern/cli/build.js +9 -0
  6. package/dist/js/modern/cli/dev.js +8 -0
  7. package/dist/js/modern/cli/index.js +3 -0
  8. package/dist/js/modern/cli/new.js +16 -0
  9. package/dist/js/modern/commands/build.js +56 -0
  10. package/dist/js/modern/commands/dev.js +29 -0
  11. package/dist/js/modern/commands/index.js +2 -0
  12. package/dist/js/modern/features/build/build-platform.js +70 -0
  13. package/dist/js/modern/features/build/build-watch.js +96 -0
  14. package/dist/js/modern/features/build/build.js +110 -0
  15. package/dist/js/modern/features/build/constants.js +66 -0
  16. package/dist/js/modern/features/build/index.js +29 -0
  17. package/dist/js/modern/features/build/logger/index.js +2 -0
  18. package/dist/js/modern/features/build/logger/logText.js +63 -0
  19. package/dist/js/modern/features/build/logger/loggerManager.js +101 -0
  20. package/dist/js/modern/features/build/utils.js +198 -0
  21. package/dist/js/modern/features/dev/index.js +41 -0
  22. package/dist/js/modern/index.js +46 -0
  23. package/dist/js/modern/locale/en.js +23 -0
  24. package/dist/js/modern/locale/index.js +10 -0
  25. package/dist/js/modern/locale/zh.js +23 -0
  26. package/dist/js/modern/schema/index.js +3 -0
  27. package/dist/js/modern/schema/output.js +29 -0
  28. package/dist/js/modern/schema/source.js +15 -0
  29. package/dist/js/modern/tasks/build-source-code.js +213 -0
  30. package/dist/js/modern/tasks/build-style.js +152 -0
  31. package/dist/js/modern/tasks/build-watch-source-code.js +144 -0
  32. package/dist/js/modern/tasks/build-watch-style.js +213 -0
  33. package/dist/js/modern/tasks/constants.js +1 -0
  34. package/dist/js/modern/tasks/copy-assets.js +108 -0
  35. package/dist/js/modern/tasks/generator-dts.js +220 -0
  36. package/dist/js/modern/types.js +0 -0
  37. package/dist/js/modern/utils/babel.js +85 -0
  38. package/dist/js/modern/utils/color.js +2 -0
  39. package/dist/js/modern/utils/copy.js +80 -0
  40. package/dist/js/modern/utils/json.js +13 -0
  41. package/dist/js/modern/utils/language.js +6 -0
  42. package/dist/js/modern/utils/logger.js +110 -0
  43. package/dist/js/modern/utils/readline.js +19 -0
  44. package/dist/js/modern/utils/tsconfig.js +15 -0
  45. package/dist/js/modern/utils/tspaths-transform/constants.js +3 -0
  46. package/dist/js/modern/utils/tspaths-transform/index.js +130 -0
  47. package/dist/js/modern/utils/tspaths-transform/utils.js +21 -0
  48. package/dist/js/modern/utils/valide.js +28 -0
  49. package/dist/js/node/cli/build.js +21 -0
  50. package/dist/js/node/cli/dev.js +20 -0
  51. package/dist/js/node/cli/index.js +44 -0
  52. package/dist/js/node/cli/new.js +28 -0
  53. package/dist/js/node/commands/build.js +76 -0
  54. package/dist/js/node/commands/dev.js +49 -0
  55. package/dist/js/node/commands/index.js +21 -0
  56. package/dist/js/node/features/build/build-platform.js +84 -0
  57. package/dist/js/node/features/build/build-watch.js +118 -0
  58. package/dist/js/node/features/build/build.js +133 -0
  59. package/dist/js/node/features/build/constants.js +79 -0
  60. package/dist/js/node/features/build/index.js +41 -0
  61. package/dist/js/node/features/build/logger/index.js +31 -0
  62. package/dist/js/node/features/build/logger/logText.js +79 -0
  63. package/dist/js/node/features/build/logger/loggerManager.js +111 -0
  64. package/dist/js/node/features/build/utils.js +231 -0
  65. package/dist/js/node/features/dev/index.js +60 -0
  66. package/dist/js/node/index.js +64 -0
  67. package/dist/js/node/locale/en.js +30 -0
  68. package/dist/js/node/locale/index.js +22 -0
  69. package/dist/js/node/locale/zh.js +30 -0
  70. package/dist/js/node/schema/index.js +14 -0
  71. package/dist/js/node/schema/output.js +36 -0
  72. package/dist/js/node/schema/source.js +22 -0
  73. package/dist/js/node/tasks/build-source-code.js +240 -0
  74. package/dist/js/node/tasks/build-style.js +168 -0
  75. package/dist/js/node/tasks/build-watch-source-code.js +156 -0
  76. package/dist/js/node/tasks/build-watch-style.js +231 -0
  77. package/dist/js/node/tasks/constants.js +8 -0
  78. package/dist/js/node/tasks/copy-assets.js +126 -0
  79. package/dist/js/node/tasks/generator-dts.js +243 -0
  80. package/dist/js/node/types.js +0 -0
  81. package/dist/js/node/utils/babel.js +99 -0
  82. package/dist/js/node/utils/color.js +12 -0
  83. package/dist/js/node/utils/copy.js +99 -0
  84. package/dist/js/node/utils/json.js +22 -0
  85. package/dist/js/node/utils/language.js +15 -0
  86. package/dist/js/node/utils/logger.js +133 -0
  87. package/dist/js/node/utils/readline.js +33 -0
  88. package/dist/js/node/utils/tsconfig.js +30 -0
  89. package/dist/js/node/utils/tspaths-transform/constants.js +10 -0
  90. package/dist/js/node/utils/tspaths-transform/index.js +155 -0
  91. package/dist/js/node/utils/tspaths-transform/utils.js +32 -0
  92. package/dist/js/node/utils/valide.js +41 -0
  93. package/dist/types/cli/build.d.ts +2 -0
  94. package/dist/types/cli/dev.d.ts +2 -0
  95. package/dist/types/cli/index.d.ts +3 -0
  96. package/dist/types/cli/new.d.ts +2 -0
  97. package/dist/types/commands/build.d.ts +16 -0
  98. package/dist/types/commands/dev.d.ts +4 -0
  99. package/dist/types/commands/index.d.ts +2 -0
  100. package/dist/types/features/build/build-platform.d.ts +6 -0
  101. package/dist/types/features/build/build-watch.d.ts +3 -0
  102. package/dist/types/features/build/build.d.ts +3 -0
  103. package/dist/types/features/build/constants.d.ts +14 -0
  104. package/dist/types/features/build/index.d.ts +3 -0
  105. package/dist/types/features/build/logger/index.d.ts +2 -0
  106. package/dist/types/features/build/logger/logText.d.ts +39 -0
  107. package/dist/types/features/build/logger/loggerManager.d.ts +39 -0
  108. package/dist/types/features/build/utils.d.ts +58 -0
  109. package/dist/types/features/dev/index.d.ts +7 -0
  110. package/dist/types/index.d.ts +17 -0
  111. package/dist/types/locale/en.d.ts +23 -0
  112. package/dist/types/locale/index.d.ts +47 -0
  113. package/dist/types/locale/zh.d.ts +23 -0
  114. package/dist/types/schema/index.d.ts +36 -0
  115. package/dist/types/schema/output.d.ts +22 -0
  116. package/dist/types/schema/source.d.ts +15 -0
  117. package/dist/types/tasks/build-source-code.d.ts +42 -0
  118. package/dist/types/tasks/build-style.d.ts +1 -0
  119. package/dist/types/tasks/build-watch-source-code.d.ts +1 -0
  120. package/dist/types/tasks/build-watch-style.d.ts +1 -0
  121. package/dist/types/tasks/constants.d.ts +1 -0
  122. package/dist/types/tasks/copy-assets.d.ts +1 -0
  123. package/dist/types/tasks/generator-dts.d.ts +1 -0
  124. package/dist/types/types.d.ts +48 -0
  125. package/dist/types/utils/babel.d.ts +8 -0
  126. package/dist/types/utils/color.d.ts +2 -0
  127. package/dist/types/utils/copy.d.ts +5 -0
  128. package/dist/types/utils/json.d.ts +4 -0
  129. package/dist/types/utils/language.d.ts +1 -0
  130. package/dist/types/utils/logger.d.ts +56 -0
  131. package/dist/types/utils/readline.d.ts +9 -0
  132. package/dist/types/utils/tsconfig.d.ts +16 -0
  133. package/dist/types/utils/tspaths-transform/constants.d.ts +1 -0
  134. package/dist/types/utils/tspaths-transform/index.d.ts +15 -0
  135. package/dist/types/utils/tspaths-transform/utils.d.ts +4 -0
  136. package/dist/types/utils/valide.d.ts +12 -0
  137. package/modern.config.js +6 -0
  138. package/package.json +95 -0
  139. package/src/.eslintrc.json +5 -0
  140. package/src/cli/build.ts +39 -0
  141. package/src/cli/dev.ts +24 -0
  142. package/src/cli/index.ts +3 -0
  143. package/src/cli/new.ts +32 -0
  144. package/src/commands/build.ts +81 -0
  145. package/src/commands/dev.ts +41 -0
  146. package/src/commands/index.ts +2 -0
  147. package/src/features/build/build-platform.ts +76 -0
  148. package/src/features/build/build-watch.ts +93 -0
  149. package/src/features/build/build.ts +111 -0
  150. package/src/features/build/constants.ts +52 -0
  151. package/src/features/build/index.ts +36 -0
  152. package/src/features/build/logger/index.ts +2 -0
  153. package/src/features/build/logger/logText.ts +80 -0
  154. package/src/features/build/logger/loggerManager.ts +132 -0
  155. package/src/features/build/utils.ts +250 -0
  156. package/src/features/dev/index.ts +62 -0
  157. package/src/index.ts +55 -0
  158. package/src/locale/en.ts +21 -0
  159. package/src/locale/index.ts +15 -0
  160. package/src/locale/zh.ts +21 -0
  161. package/src/schema/index.ts +4 -0
  162. package/src/schema/output.ts +34 -0
  163. package/src/schema/schema.d.ts +13 -0
  164. package/src/schema/source.ts +16 -0
  165. package/src/tasks/build-source-code.ts +245 -0
  166. package/src/tasks/build-style.ts +175 -0
  167. package/src/tasks/build-watch-source-code.ts +185 -0
  168. package/src/tasks/build-watch-style.ts +260 -0
  169. package/src/tasks/constants.ts +1 -0
  170. package/src/tasks/copy-assets.ts +117 -0
  171. package/src/tasks/generator-dts.ts +277 -0
  172. package/src/type.d.ts +1 -0
  173. package/src/types.ts +63 -0
  174. package/src/utils/babel.ts +100 -0
  175. package/src/utils/color.ts +3 -0
  176. package/src/utils/copy.ts +70 -0
  177. package/src/utils/json.ts +13 -0
  178. package/src/utils/language.ts +9 -0
  179. package/src/utils/logger.ts +144 -0
  180. package/src/utils/readline.ts +28 -0
  181. package/src/utils/tsconfig.ts +37 -0
  182. package/src/utils/tspaths-transform/constants.ts +19 -0
  183. package/src/utils/tspaths-transform/index.ts +139 -0
  184. package/src/utils/tspaths-transform/utils.ts +25 -0
  185. package/src/utils/valide.ts +37 -0
  186. package/tsconfig.json +13 -0
  187. package/types.d.ts +1 -0
@@ -0,0 +1,15 @@
1
+ import { Import } from '@modern-js/utils';
2
+
3
+ import { ZH_LOCALE } from './zh';
4
+ import { EN_LOCALE } from './en';
5
+
6
+ const i18nPlugin: typeof import('@modern-js/plugin-i18n') = Import.lazy(
7
+ '@modern-js/plugin-i18n',
8
+ require,
9
+ );
10
+
11
+ const i18n = new i18nPlugin.I18n();
12
+
13
+ const localeKeys = i18n.init('zh', { zh: ZH_LOCALE, en: EN_LOCALE });
14
+
15
+ export { i18n, localeKeys };
@@ -0,0 +1,21 @@
1
+ export const ZH_LOCALE = {
2
+ command: {
3
+ build: {
4
+ describe: '构建模块命令',
5
+ watch: '使用 Watch 模式构建模块',
6
+ tsconfig: '指定 tsconfig.json 文件的路径',
7
+ style_only: '只构建样式文件',
8
+ platform: '构建其他平台产物',
9
+ no_tsc: '关闭 tsc 编译',
10
+ no_clear: '不清理产物目录',
11
+ },
12
+ dev: { describe: '本地开发命令' },
13
+ new: {
14
+ describe: '模块化工程方案中执行生成器',
15
+ debug: '开启 Debug 模式,打印调试日志信息',
16
+ config: '生成器运行默认配置(JSON 字符串)',
17
+ distTag: '生成器使用特殊的 npm Tag 版本',
18
+ registry: '生成器运行过程中定制 npm Registry',
19
+ },
20
+ },
21
+ };
@@ -0,0 +1,4 @@
1
+ import { sourceSchema } from './source';
2
+ import { outputSchema } from './output';
3
+
4
+ export const addSchema = () => [...sourceSchema, ...outputSchema];
@@ -0,0 +1,34 @@
1
+ const PACKAGE_MODE_LIST = [
2
+ 'universal-js',
3
+ 'universal-js-lite',
4
+ 'browser-js',
5
+ 'browser-js-lite',
6
+ 'node-js',
7
+ ];
8
+
9
+ export const outputSchema = [
10
+ {
11
+ target: 'output.packageMode',
12
+ schema: { enum: PACKAGE_MODE_LIST },
13
+ },
14
+ {
15
+ target: 'output.packageFields',
16
+ schema: { typeof: 'object' },
17
+ },
18
+ {
19
+ target: 'output.disableTsChecker',
20
+ schema: { typeof: 'boolean' },
21
+ },
22
+ {
23
+ target: 'output.enableSourceMap',
24
+ schema: { typeof: 'boolean' },
25
+ },
26
+ {
27
+ target: 'output.importStyle',
28
+ schema: {
29
+ enum: ['compiled-code', 'source-code'],
30
+ // TODO: 目前default是无效的
31
+ default: 'source-code',
32
+ },
33
+ },
34
+ ];
@@ -0,0 +1,13 @@
1
+ // import '@modern-js/core';
2
+ // import { PackageModeType, IPackageFields } from '../types';
3
+
4
+ // declare module '@modern-js/core' {
5
+ // interface OutputConfig {
6
+ // packageMode: PackageModeType;
7
+ // packageFields: IPackageFields;
8
+ // }
9
+ // interface NormalizedSourceConfig {
10
+ // enableBlockRuntime: boolean;
11
+ // jsxTransformRuntime: 'classic' | 'automatic';
12
+ // }
13
+ // }
@@ -0,0 +1,16 @@
1
+ export const sourceSchema = [
2
+ // 启动区块运行时
3
+ {
4
+ target: 'source.enableBlockRuntime',
5
+ schema: { type: 'boolean' },
6
+ },
7
+ {
8
+ target: 'source.jsxTransformRuntime',
9
+ schema: {
10
+ // https://babeljs.io/docs/en/babel-preset-react#runtime
11
+ enum: ['classic', 'automatic'],
12
+ // TODO: 目前default是无效的
13
+ default: 'automatic',
14
+ },
15
+ },
16
+ ];
@@ -0,0 +1,245 @@
1
+ import { Import, fs } from '@modern-js/utils';
2
+ import type { NormalizedConfig } from '@modern-js/core';
3
+ import type { BabelOptions, IVirtualDist } from '@modern-js/babel-compiler';
4
+ import type { ITsconfig } from '../types';
5
+
6
+ const babelCompiler: typeof import('@modern-js/babel-compiler') = Import.lazy(
7
+ '@modern-js/babel-compiler',
8
+ require,
9
+ );
10
+ const glob: typeof import('glob') = Import.lazy('glob', require);
11
+ const argv: typeof import('process.argv').default = Import.lazy(
12
+ 'process.argv',
13
+ require,
14
+ );
15
+ const pluginNode: typeof import('@modern-js/plugin/node') = Import.lazy(
16
+ '@modern-js/plugin/node',
17
+ require,
18
+ );
19
+ const core: typeof import('@modern-js/core') = Import.lazy(
20
+ '@modern-js/core',
21
+ require,
22
+ );
23
+ const bc: typeof import('../utils/babel') = Import.lazy(
24
+ '../utils/babel',
25
+ require,
26
+ );
27
+ const ts: typeof import('../utils/tsconfig') = Import.lazy(
28
+ '../utils/tsconfig',
29
+ require,
30
+ );
31
+
32
+ export enum Compiler {
33
+ babel,
34
+ esbuild,
35
+ swc,
36
+ }
37
+
38
+ interface IBuildSourceCodeConfig {
39
+ babelConfig: BabelOptions;
40
+ srcRootDir: string;
41
+ willCompilerDirOrFile: string;
42
+ distDir: string;
43
+ compiler: Compiler;
44
+ projectData: {
45
+ appDirectory: string;
46
+ };
47
+ sourceMaps?: boolean;
48
+ tsconfigPath: string;
49
+ }
50
+
51
+ const runBabelCompiler = async (
52
+ willCompilerFiles: string[],
53
+ config: IBuildSourceCodeConfig,
54
+ babelConfig: BabelOptions = {},
55
+ ) => {
56
+ const { srcRootDir, distDir } = config;
57
+ // TODO: 判断lynx模式下,修改distFileExtMap: {'js': 'js', 'jsx': 'jsx', 'ts': 'js', 'tsx': 'jsx'}
58
+ return babelCompiler.compiler(
59
+ {
60
+ quiet: true,
61
+ enableVirtualDist: true,
62
+ rootDir: srcRootDir,
63
+ filenames: willCompilerFiles,
64
+ distDir,
65
+ },
66
+ babelConfig,
67
+ );
68
+ };
69
+
70
+ export const getWillCompilerCode = (
71
+ srcDirOrFile: string,
72
+ option: { tsconfig: ITsconfig | null; isTsProject: boolean },
73
+ ) => {
74
+ const { tsconfig, isTsProject } = option;
75
+ // 如果是一个文件路径,则直接返回
76
+ if (fs.existsSync(srcDirOrFile) && fs.lstatSync(srcDirOrFile).isFile()) {
77
+ return [srcDirOrFile];
78
+ }
79
+
80
+ const getExts = (isTs: boolean) => {
81
+ // TODO: 是否受控tsconfig.json 里的jsx配置
82
+ let exts = [];
83
+ if (isTs) {
84
+ exts = tsconfig?.compilerOptions?.allowJs
85
+ ? ['.ts', '.tsx', '.js', '.jsx']
86
+ : ['.ts', '.tsx'];
87
+ } else {
88
+ exts = ['.js', '.jsx'];
89
+ }
90
+
91
+ return exts;
92
+ };
93
+
94
+ const exts = getExts(isTsProject);
95
+ const globPattern = `${srcDirOrFile}/**/*{${exts.join(',')}}`;
96
+ const files = glob.sync(globPattern, {
97
+ ignore: [`${srcDirOrFile}/**/*.d.ts`],
98
+ });
99
+
100
+ return files;
101
+ };
102
+
103
+ export const buildSourceCode = async (config: IBuildSourceCodeConfig) => {
104
+ const {
105
+ compiler,
106
+ willCompilerDirOrFile,
107
+ tsconfigPath,
108
+ sourceMaps,
109
+ babelConfig,
110
+ } = config;
111
+ const tsconfig = ts.readTsConfig(tsconfigPath);
112
+ const willCompilerFiles = getWillCompilerCode(willCompilerDirOrFile, {
113
+ tsconfig,
114
+ isTsProject: Boolean(tsconfig),
115
+ });
116
+
117
+ let distSet = null;
118
+ if (compiler === Compiler.babel) {
119
+ distSet = await runBabelCompiler(willCompilerFiles, config, {
120
+ ...babelConfig,
121
+ sourceMaps,
122
+ });
123
+ } else {
124
+ distSet = {
125
+ code: 1,
126
+ message: 'no compiler',
127
+ };
128
+ }
129
+
130
+ return distSet;
131
+ };
132
+
133
+ const generatorRealFiles = (virtualDists: IVirtualDist[]) => {
134
+ for (const virtualDist of virtualDists) {
135
+ const { distPath, code, sourcemap, sourceMapPath } = virtualDist;
136
+ fs.ensureFileSync(distPath);
137
+ fs.writeFileSync(distPath, code);
138
+ if (sourcemap.length > 0) {
139
+ fs.ensureFileSync(sourceMapPath);
140
+ fs.writeFileSync(sourceMapPath, sourcemap);
141
+ }
142
+ }
143
+ };
144
+
145
+ export const initEnv = ({ syntax, type }: ITaskConfig) => {
146
+ if (syntax === 'es6+' && type === 'commonjs') {
147
+ return 'nodejs';
148
+ } else if (syntax === 'es6+' && type === 'module') {
149
+ return 'modern';
150
+ } else if (syntax === 'es5' && type === 'module') {
151
+ return 'legacy-browser';
152
+ }
153
+
154
+ return '';
155
+ };
156
+
157
+ interface ITaskConfig {
158
+ srcRootDir: string; // 源码的根目录
159
+ willCompilerDirOrFile: string; // 用于编译的源码文件或者源码目录
160
+ distDir: string;
161
+ appDirectory: string;
162
+ sourceMaps: boolean;
163
+ syntax: 'es5' | 'es6+';
164
+ type: 'module' | 'commonjs';
165
+ tsconfigPath: string;
166
+ copyDirs?: string;
167
+ compiler?: 'babel' | 'esbuild' | 'swc';
168
+ watch: boolean;
169
+ }
170
+ const defaultConfig: ITaskConfig = {
171
+ srcRootDir: `${process.cwd()}/src`,
172
+ willCompilerDirOrFile: `${process.cwd()}/src`,
173
+ distDir: './dist/js/temp',
174
+ compiler: 'babel',
175
+ appDirectory: '',
176
+ sourceMaps: false,
177
+ tsconfigPath: '',
178
+ syntax: 'es5',
179
+ type: 'module',
180
+ watch: false,
181
+ };
182
+ const taskMain = async ({
183
+ modernConfig,
184
+ }: {
185
+ modernConfig: NormalizedConfig;
186
+ }) => {
187
+ // 执行脚本的参数处理和相关需要配置的获取
188
+ const processArgv = argv(process.argv.slice(2));
189
+ const config = processArgv<ITaskConfig>(defaultConfig);
190
+ // process.env.BUILD_MODE = initEnv(config);
191
+ const compiler = Compiler.babel; // 目前暂时只支持 babel
192
+ const babelConfig = bc.resolveBabelConfig(config.appDirectory, modernConfig, {
193
+ sourceAbsDir: config.srcRootDir,
194
+ tsconfigPath: config.tsconfigPath,
195
+ syntax: config.syntax,
196
+ type: config.type,
197
+ });
198
+
199
+ const {
200
+ code,
201
+ message,
202
+ messageDetails,
203
+ virtualDists = [],
204
+ } = await buildSourceCode({
205
+ distDir: config.distDir,
206
+ srcRootDir: config.srcRootDir,
207
+ willCompilerDirOrFile: config.willCompilerDirOrFile,
208
+ sourceMaps: config.sourceMaps,
209
+ compiler,
210
+ projectData: { appDirectory: config.appDirectory },
211
+ tsconfigPath: config.tsconfigPath,
212
+ babelConfig,
213
+ });
214
+
215
+ if (code === 0) {
216
+ generatorRealFiles(virtualDists);
217
+ // 执行成功log使用 console.info
218
+ console.info('[Babel Compiler]: Successfully');
219
+ } else if (messageDetails && messageDetails.length > 0) {
220
+ console.error(message);
221
+ for (const detail of messageDetails || []) {
222
+ console.error(detail.content);
223
+ }
224
+ }
225
+
226
+ if (code === 0 && config.copyDirs) {
227
+ const copyList = config.copyDirs.split(',');
228
+ for (const copyDir of copyList) {
229
+ fs.ensureDirSync(copyDir);
230
+ fs.copySync(config.distDir, copyDir);
231
+ }
232
+ }
233
+ };
234
+
235
+ (async () => {
236
+ pluginNode.enable();
237
+ const { resolved } = await core.cli.init();
238
+ await core.manager.run(async () => {
239
+ try {
240
+ await taskMain({ modernConfig: resolved });
241
+ } catch (e) {
242
+ console.error(e);
243
+ }
244
+ });
245
+ })();
@@ -0,0 +1,175 @@
1
+ import * as path from 'path';
2
+ import { fs, Import } from '@modern-js/utils';
3
+ import type { NormalizedConfig, IAppContext } from '@modern-js/core';
4
+ import type { ICompilerResult, PostcssOption } from '@modern-js/style-compiler';
5
+ import type { ModuleToolsOutput } from '../types';
6
+
7
+ const cssConfig: typeof import('@modern-js/css-config') = Import.lazy(
8
+ '@modern-js/css-config',
9
+ require,
10
+ );
11
+ const core: typeof import('@modern-js/core') = Import.lazy(
12
+ '@modern-js/core',
13
+ require,
14
+ );
15
+ const compiler: typeof import('@modern-js/style-compiler') = Import.lazy(
16
+ '@modern-js/style-compiler',
17
+ require,
18
+ );
19
+ const glob: typeof import('glob') = Import.lazy('glob', require);
20
+ const hooks: typeof import('@modern-js/module-tools-hooks') = Import.lazy(
21
+ '@modern-js/module-tools-hooks',
22
+ require,
23
+ );
24
+ const pluginNode: typeof import('@modern-js/plugin/node') = Import.lazy(
25
+ '@modern-js/plugin/node',
26
+ require,
27
+ );
28
+
29
+ const STYLE_DIRS = 'styles';
30
+ const SRC_STYLE_DIRS = 'src';
31
+
32
+ const checkStylesDirExist = (option: { appDirectory: string }) => {
33
+ const { appDirectory } = option;
34
+ return fs.existsSync(path.join(appDirectory, STYLE_DIRS));
35
+ };
36
+
37
+ const generatorFileOrLogError = (
38
+ result: ICompilerResult,
39
+ successMessage = '',
40
+ ) => {
41
+ if (result.code === 0 && result.dists.length > 0) {
42
+ for (const file of result.dists) {
43
+ fs.ensureFileSync(file.filename);
44
+ fs.writeFileSync(file.filename, file.content);
45
+ }
46
+ if (successMessage) {
47
+ console.info(successMessage);
48
+ }
49
+ } else {
50
+ for (const file of result.errors) {
51
+ console.error(file.error);
52
+ }
53
+ }
54
+ };
55
+
56
+ const getPostcssOption = (
57
+ appDirectory: string,
58
+ modernConfig: NormalizedConfig,
59
+ ): PostcssOption => {
60
+ const postcssOption = cssConfig.getPostcssConfig(
61
+ appDirectory,
62
+ modernConfig,
63
+ false,
64
+ );
65
+ return {
66
+ plugins: postcssOption?.postcssOptions?.plugins || [],
67
+ enableSourceMap: (postcssOption as any)?.sourceMap || false,
68
+ options: {},
69
+ } as any;
70
+ };
71
+
72
+ const copyOriginStyleFiles = ({
73
+ targetDir,
74
+ outputDir,
75
+ }: {
76
+ targetDir: string;
77
+ outputDir: string;
78
+ }) => {
79
+ const styleFiles = glob.sync(`${targetDir}/**/*.{css,sass,scss,less}`);
80
+ if (styleFiles.length > 0) {
81
+ fs.ensureDirSync(outputDir);
82
+ }
83
+ for (const styleFile of styleFiles) {
84
+ const file = path.relative(targetDir, styleFile);
85
+ fs.copyFileSync(styleFile, path.join(outputDir, file));
86
+ }
87
+ };
88
+
89
+ const taskMain = async ({
90
+ modernConfig,
91
+ appContext,
92
+ }: {
93
+ modernConfig: NormalizedConfig;
94
+ appContext: IAppContext;
95
+ }) => {
96
+ const {
97
+ assetsPath = 'styles',
98
+ path: outputPath = 'dist',
99
+ jsPath = 'js',
100
+ } = modernConfig.output as ModuleToolsOutput;
101
+ const { appDirectory } = appContext;
102
+
103
+ const lessOption = await (core.mountHook() as any).moduleLessConfig(
104
+ { modernConfig },
105
+ // eslint-disable-next-line @typescript-eslint/require-await
106
+ { onLast: async (_: any) => null as any },
107
+ );
108
+ const sassOption = await (core.mountHook() as any).moduleSassConfig(
109
+ { modernConfig },
110
+ // eslint-disable-next-line @typescript-eslint/require-await
111
+ { onLast: async (_: any) => null as any },
112
+ );
113
+ const postcssOption = getPostcssOption(appDirectory, modernConfig);
114
+ const { importStyle } = modernConfig.output as ModuleToolsOutput;
115
+ const existStylesDir = checkStylesDirExist({ appDirectory });
116
+ // 编译 styles 目录样式
117
+ if (existStylesDir) {
118
+ const styleResult = await compiler.styleCompiler({
119
+ projectDir: appDirectory,
120
+ stylesDir: path.resolve(appDirectory, STYLE_DIRS),
121
+ outDir: path.join(appDirectory, outputPath, assetsPath),
122
+ enableVirtualDist: true,
123
+ compilerOption: {
124
+ less: lessOption,
125
+ sass: sassOption,
126
+ postcss: postcssOption,
127
+ },
128
+ });
129
+ generatorFileOrLogError(
130
+ styleResult!,
131
+ `[Style Compiler] Successfully for 'styles' dir`,
132
+ );
133
+ }
134
+
135
+ // 编译 src 内的样式代码
136
+ const srcDir = path.resolve(appDirectory, SRC_STYLE_DIRS);
137
+ const outputDirtoSrc = path.join(
138
+ appDirectory,
139
+ outputPath,
140
+ jsPath,
141
+ assetsPath,
142
+ );
143
+ if (importStyle === 'compiled-code') {
144
+ const srcStyleResult = await compiler.styleCompiler({
145
+ projectDir: appDirectory,
146
+ stylesDir: srcDir,
147
+ outDir: outputDirtoSrc,
148
+ enableVirtualDist: true,
149
+ compilerOption: {
150
+ less: lessOption,
151
+ sass: sassOption,
152
+ postcss: postcssOption,
153
+ },
154
+ });
155
+ generatorFileOrLogError(
156
+ srcStyleResult!,
157
+ `[Style Compiler] Successfully for 'src' dir`,
158
+ );
159
+ } else {
160
+ copyOriginStyleFiles({ targetDir: srcDir, outputDir: outputDirtoSrc });
161
+ }
162
+ };
163
+
164
+ (async () => {
165
+ pluginNode.enable();
166
+ hooks.buildLifeCycle();
167
+ const { resolved: modernConfig, appContext } = await core.cli.init();
168
+ await core.manager.run(async () => {
169
+ try {
170
+ await taskMain({ modernConfig, appContext });
171
+ } catch (e: any) {
172
+ console.error(e.toString());
173
+ }
174
+ });
175
+ })();