@deot/dev-builder 1.1.1 → 2.0.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.
package/README.md CHANGED
@@ -3,11 +3,37 @@
3
3
  打包
4
4
 
5
5
  - 优先执行`scripts`下的`build`和`build:types`,如果声明`build`,打包由用户管理,`build:types`,类型编译由用户管理
6
+ - 可被打包的文件匹配:`src/index.*.(j|t|s?cs)s`
6
7
 
8
+ ## 自定义配置
7
9
 
8
- ## 其它
10
+ 提供环境变量`BUILD_OPTIONS`
9
11
 
10
- - 目前依赖`rollup`打包,后续考虑读取`rollup.config.js`
11
- - 如果改成`vite`打包,则考虑读取配置`vite.config.js`
12
+ ```ts
13
+ interface BUILD_OPTIONS {
14
+ packageFolderName?: string;
15
+ workspace?: string;
16
+ watch: boolean;
17
+ coverage: boolean;
18
+ }
19
+ ```
12
20
 
13
- 打包输出文件`index.[format].js` + `index.d.ts`
21
+ 根目录创建`build.config.ts`, 可以选择`configShared`合并或单独基于`BUILD_OPTIONS`配置
22
+ > 也可以是`z.build.config.ts`, 前缀主要是置底
23
+
24
+ ```ts
25
+ import { mergeConfig, defineConfig } from 'vite';
26
+ import configShared from '@deot/dev-builder/shared.config';
27
+
28
+ export default mergeConfig(
29
+ configShared,
30
+ defineConfig({
31
+ // custom config
32
+ plugins: [
33
+ vue(),
34
+ react()
35
+ ]
36
+ })
37
+ );
38
+ ```
39
+ 取`build.config.ts`, 是为了方便从`build`转其他测试工具时,可以不改变文件名
@@ -0,0 +1,76 @@
1
+ // this the shared base config for all packages.
2
+ {
3
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
4
+ "compiler": {
5
+ "overrideTsconfig": {
6
+ "compilerOptions": {
7
+ "paths": null
8
+ }
9
+ }
10
+ },
11
+ "apiReport": {
12
+ "enabled": true,
13
+ "reportFolder": "<projectFolder>/temp/"
14
+ },
15
+
16
+ "docModel": {
17
+ "enabled": true
18
+ },
19
+
20
+ "dtsRollup": {
21
+ "enabled": true,
22
+ "untrimmedFilePath": ""
23
+ },
24
+
25
+ "tsdocMetadata": {
26
+ "enabled": false
27
+ },
28
+
29
+ "messages": {
30
+ "compilerMessageReporting": {
31
+ "default": {
32
+ "logLevel": "warning"
33
+ }
34
+ },
35
+
36
+ "extractorMessageReporting": {
37
+ "default": {
38
+ "logLevel": "warning",
39
+ "addToApiReportFile": true
40
+ },
41
+
42
+ "ae-missing-release-tag": {
43
+ "logLevel": "none"
44
+ },
45
+ "ae-wrong-input-file-type": {
46
+ "logLevel": "none"
47
+ }
48
+ },
49
+
50
+ "tsdocMessageReporting": {
51
+ "default": {
52
+ "logLevel": "warning"
53
+ },
54
+
55
+ "tsdoc-undefined-tag": {
56
+ "logLevel": "none"
57
+ },
58
+
59
+ "tsdoc-escape-greater-than": {
60
+ "logLevel": "none"
61
+ },
62
+
63
+ "tsdoc-malformed-inline-tag": {
64
+ "logLevel": "none"
65
+ },
66
+
67
+ "tsdoc-escape-right-brace": {
68
+ "logLevel": "none"
69
+ },
70
+
71
+ "tsdoc-unnecessary-backslash": {
72
+ "logLevel": "none"
73
+ }
74
+ }
75
+ }
76
+ }
package/dist/index.cjs.js CHANGED
@@ -1,233 +1,282 @@
1
1
  'use strict';
2
2
 
3
- var devShared = require('@deot/dev-shared');
4
- var path = require('node:path');
5
- var node_module = require('node:module');
6
- var fs = require('fs-extra');
7
- var typescript = require('@rollup/plugin-typescript');
8
- var pluginNodeResolve = require('@rollup/plugin-node-resolve');
9
- var commonjs = require('@rollup/plugin-commonjs');
10
- var replace = require('@rollup/plugin-replace');
11
- var rollup = require('rollup');
12
- var apiExtractor = require('@microsoft/api-extractor');
13
- var chalk = require('chalk');
14
- var ora = require('ora');
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const devShared = require('@deot/dev-shared');
6
+ const path = require('node:path');
7
+ const node_module = require('node:module');
8
+ const fs = require('fs-extra');
9
+ const chalk = require('chalk');
10
+ const ora = require('ora');
11
+ const node_url = require('node:url');
12
+ const vite = require('vite');
13
+ const sass = require('sass');
14
+ const postcss = require('postcss');
15
+ const atImport = require('postcss-import');
16
+ const atUrl = require('postcss-url');
17
+ const flexBugs = require('postcss-flexbugs-fixes');
18
+ const cssnano = require('cssnano');
19
+ const autoprefixer = require('autoprefixer');
20
+ const apiExtractor = require('@microsoft/api-extractor');
15
21
 
16
22
  function _interopNamespaceDefault(e) {
17
- var n = Object.create(null);
18
- if (e) {
19
- Object.keys(e).forEach(function (k) {
20
- if (k !== 'default') {
21
- var d = Object.getOwnPropertyDescriptor(e, k);
22
- Object.defineProperty(n, k, d.get ? d : {
23
- enumerable: true,
24
- get: function () { return e[k]; }
25
- });
26
- }
27
- });
28
- }
29
- n.default = e;
30
- return Object.freeze(n);
23
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
24
+ if (e) {
25
+ for (const k in e) {
26
+ if (k !== 'default') {
27
+ const d = Object.getOwnPropertyDescriptor(e, k);
28
+ Object.defineProperty(n, k, d.get ? d : {
29
+ enumerable: true,
30
+ get: () => e[k]
31
+ });
32
+ }
33
+ }
34
+ }
35
+ n.default = e;
36
+ return Object.freeze(n);
31
37
  }
32
38
 
33
- var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
39
+ const path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
34
40
 
35
- const require$ = node_module.createRequire(process.cwd());
36
- class Build {
37
- packageDir;
38
- packageName;
39
- packageOptions;
40
- config;
41
- commandOptions;
42
- constructor(config, commandOptions) {
43
- const { workspace, packageDir, packageName } = devShared.Locals.impl();
44
- if (typeof config === 'string') {
45
- let packageFolderName = config;
46
- let packageDir$ = path__namespace.resolve(packageDir, packageFolderName);
47
- let input = fs.existsSync(packageDir$ + '/src/index.ts')
48
- ? packageDir$ + '/src/index.ts'
49
- : fs.existsSync(packageDir$ + '/src/index.js')
50
- ? packageDir$ + '/src/index.js'
51
- : '';
52
- config = {
53
- dir: packageDir$,
54
- name: packageFolderName || 'index',
55
- input,
56
- output: [
57
- {
58
- file: packageDir$ + '/dist/index.es.js',
59
- format: 'es',
60
- exports: 'named',
61
- sourcemap: false
62
- },
63
- {
64
- file: packageDir$ + '/dist/index.iife.js',
65
- format: 'iife',
66
- name: packageName,
67
- },
68
- {
69
- file: packageDir$ + '/dist/index.cjs.js',
70
- format: 'cjs'
71
- }
72
- ].filter(i => {
73
- return commandOptions.formats.includes(i.format);
74
- })
75
- };
76
- }
77
- this.packageDir = path__namespace.resolve(packageDir, workspace ? `./${config.name}` : '');
78
- this.packageName = config.name === 'index'
79
- ? packageName
80
- : `${packageName}-${config.name}`;
81
- this.packageOptions = require$(`${this.packageDir}/package.json`);
82
- this.config = config;
83
- this.commandOptions = commandOptions;
41
+ const dirname$1 = path__namespace.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs.js', document.baseURI).href))));
42
+ const run$3 = async (options) => {
43
+ const locals = devShared.Locals.impl();
44
+ const { cwd } = locals;
45
+ const { packageName, packageDir, packageOptions } = options || {};
46
+ const stats = [];
47
+ const srcDir = path__namespace.resolve(packageDir, "./src");
48
+ const outDir = path__namespace.resolve(packageDir, "./dist");
49
+ let files = fs.existsSync(srcDir) ? fs.readdirSync(srcDir).filter((i) => /^index(.*)\.(t|j)s$/.test(i)) : [];
50
+ if (!files.length)
51
+ return stats;
52
+ process.env.BUILD_OPTIONS = encodeURIComponent(JSON.stringify({
53
+ files,
54
+ packageName,
55
+ packageDir,
56
+ packageOptions
57
+ }));
58
+ let options$ = {};
59
+ if (fs.existsSync(`${cwd}/build.config.ts`)) {
60
+ options$.configFile = path__namespace.relative(cwd, path__namespace.resolve(cwd, "./build.config.ts"));
61
+ } else if (fs.existsSync(`${cwd}/z.build.config.ts`)) {
62
+ options$.configFile = path__namespace.relative(cwd, path__namespace.resolve(cwd, "./z.build.config.ts"));
63
+ } else {
64
+ options$.configFile = path__namespace.relative(cwd, path__namespace.resolve(dirname$1, "../shared.config.ts"));
65
+ }
66
+ await vite.build(options$);
67
+ let outputs = fs.readdirSync(outDir).filter((i) => /^index(.*)(?!=\.d)\.js$/.test(i));
68
+ outputs.forEach((file) => {
69
+ let stat = fs.statSync(path__namespace.resolve(outDir, file));
70
+ stats.push({
71
+ file: file.replace(/^(.*)(\..*\.js)/, "$1.ts"),
72
+ format: file.replace(/.*\.(.*)\.js/, "$1"),
73
+ size: stat.size
74
+ });
75
+ });
76
+ return stats;
77
+ };
78
+
79
+ const run$2 = async (options) => {
80
+ const { packageDir } = options || {};
81
+ const srcDir = path__namespace.resolve(packageDir, "./src");
82
+ const styles = fs.existsSync(srcDir) ? fs.readdirSync(srcDir).filter((i) => /^index(.*)\.s?css$/.test(i)) : [];
83
+ const stats = [];
84
+ await styles.reduce(
85
+ (preProcess, file) => {
86
+ preProcess = preProcess.then(() => {
87
+ let filepath = path__namespace.resolve(srcDir, file);
88
+ const data = sass.compile(filepath, { style: "compressed" });
89
+ return postcss().use(atImport()).use(atUrl()).use(flexBugs()).use(cssnano()).use(autoprefixer({ remove: false })).process(data.css, { from: filepath });
90
+ }).then((source) => {
91
+ let output = path__namespace.resolve(packageDir, `./dist/${file.replace(/\.scss$/g, ".css")}`);
92
+ fs.outputFileSync(output, source.css);
93
+ return fs.stat(output);
94
+ }).then((stat) => {
95
+ stats.push({
96
+ file,
97
+ size: stat.size
98
+ });
99
+ });
100
+ return preProcess;
101
+ },
102
+ Promise.resolve()
103
+ );
104
+ return stats;
105
+ };
106
+
107
+ const dirname = path__namespace.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs.js', document.baseURI).href))));
108
+ const run$1 = async (options) => {
109
+ const { workspace } = devShared.Locals.impl();
110
+ const { packageDir, packageFolderName, packageOptions, commandOptions } = options;
111
+ const done = () => {
112
+ const stats = [];
113
+ let fullpath = `${packageDir}/dist/index.d.ts`;
114
+ if (fs.existsSync(fullpath)) {
115
+ let stat = fs.statSync(fullpath);
116
+ stats.push({
117
+ file: "index.d.ts",
118
+ size: stat.size
119
+ });
84
120
  }
85
- async process() {
86
- const { cwd, workspace } = devShared.Locals.impl();
87
- const { config, packageOptions, packageName, packageDir } = this;
88
- if (workspace
89
- && packageOptions?.scripts?.build
90
- && packageDir !== cwd) {
91
- await devShared.Shell.spawn(`npm`, ['run', 'build'], {
92
- cwd: packageDir
93
- });
94
- return;
95
- }
96
- if (!config.input)
97
- return;
98
- const spinner = ora(`${packageName} Build ...`);
99
- try {
100
- spinner.start();
101
- await fs.emptyDir(`${packageDir}/dist`);
102
- const stats = await this.buildSources();
103
- await this.buildTypes();
104
- spinner.stop();
105
- devShared.Logger.log(`${chalk.cyan(`${packageName}`)}: ${chalk.green('Success')}`);
106
- stats.forEach((stat) => {
107
- devShared.Logger.log(`${chalk.green(stat.format.toUpperCase())}: ${devShared.Utils.formatBytes(stat.size)}`);
108
- });
109
- }
110
- catch (e) {
111
- devShared.Logger.log('Error!', e);
112
- throw e;
121
+ return stats;
122
+ };
123
+ if (!commandOptions.dts) {
124
+ return done();
125
+ }
126
+ if (workspace && packageOptions?.scripts?.["build:types"]) {
127
+ await devShared.Shell.spawn(`npm`, ["run", "build:types"], {
128
+ cwd: packageDir
129
+ });
130
+ return done();
131
+ }
132
+ let tempDir = `${packageDir}/dist/temp`;
133
+ let rootDir = path__namespace.relative(tempDir, process.cwd());
134
+ fs.outputFileSync(`${tempDir}/tsconfig.json`, JSON.stringify({
135
+ extends: `${rootDir}/tsconfig.json`,
136
+ compilerOptions: {
137
+ declaration: true,
138
+ emitDeclarationOnly: true,
139
+ rootDir,
140
+ outDir: "."
141
+ },
142
+ include: [
143
+ path__namespace.relative(tempDir, path__namespace.resolve(packageDir, `src/*`))
144
+ ]
145
+ }, null, " "));
146
+ await devShared.Shell.spawn("tsc", ["-p", `${tempDir}/tsconfig.json`]);
147
+ const configPath = `${tempDir}/api-extractor.json`;
148
+ fs.outputFileSync(configPath, JSON.stringify({
149
+ extends: path__namespace.relative(tempDir, path__namespace.resolve(dirname, "../api-extractor.shared.json")),
150
+ mainEntryPointFilePath: `.${workspace ? "/packages/" : ""}${packageFolderName}/src/index.d.ts`,
151
+ // workspace、时以temp/packages/*/src结构,否则APIExtractor会报错
152
+ dtsRollup: {
153
+ publicTrimmedFilePath: "../index.d.ts"
154
+ }
155
+ }, null, " "));
156
+ const result = apiExtractor.Extractor.invoke(
157
+ apiExtractor.ExtractorConfig.loadFileAndPrepare(configPath),
158
+ {
159
+ localBuild: true,
160
+ showVerboseMessages: false,
161
+ // 去掉版本提示
162
+ messageCallback: (message) => {
163
+ if (message.messageId === "console-compiler-version-notice" || message.messageId === "console-preamble") {
164
+ message.handled = true;
113
165
  }
166
+ }
114
167
  }
115
- async buildSources() {
116
- const { workspace } = devShared.Locals.impl();
117
- const { name, input, output } = this.config;
118
- const { packageOptions } = this;
119
- const external = Object
120
- .keys({
121
- ...packageOptions.dependencies,
122
- ...packageOptions.peerDependencies
123
- })
124
- .map(i => new RegExp(`^${i}$`));
125
- const source = workspace ? `${workspace}/${name}/**/*` : 'src/**/*';
126
- const shims = workspace ? `${workspace}/shims.d.ts` : 'shims.d.ts';
127
- const outDir = workspace ? `${workspace}/${name}/dist` : 'dist';
128
- const builder = await rollup.rollup({
129
- input,
130
- external: [
131
- /^node:/,
132
- /^[a-zA-Z@]/,
133
- ...external
134
- ],
135
- plugins: [
136
- typescript({
137
- include: [source, shims],
138
- exclude: ['dist'],
139
- compilerOptions: {
140
- rootDir: '.',
141
- outDir,
142
- declaration: true
143
- }
144
- }),
145
- commonjs({ extensions: ['.js', '.ts'] }),
146
- pluginNodeResolve.nodeResolve(),
147
- replace({
148
- '1.1.0': `'${packageOptions.version}'`,
149
- false: 'false',
150
- true: true
151
- })
152
- ]
153
- });
154
- await Promise.all(output.map(builder.write));
155
- const stats = [];
156
- await output.reduce((pre, cur, index) => {
157
- pre
158
- .then(() => fs.stat(cur.file))
159
- .then((stat) => {
160
- stats[index] = {
161
- format: cur.format,
162
- size: stat.size
163
- };
164
- });
165
- return pre;
166
- }, Promise.resolve());
167
- return stats;
168
+ );
169
+ if (!result.succeeded) {
170
+ devShared.Logger.error(
171
+ `API Extractor completed with ${result.errorCount} errors and ${result.warningCount} warnings`
172
+ );
173
+ process.exitCode = 1;
174
+ }
175
+ await fs.remove(`${packageDir}/dist/temp`);
176
+ return done();
177
+ };
178
+
179
+ const require$ = node_module.createRequire(process.cwd());
180
+ class Build {
181
+ packageDir;
182
+ packageFolderName;
183
+ packageSourceDir;
184
+ packageName;
185
+ packageOptions;
186
+ commandOptions;
187
+ constructor(packageFolderName, commandOptions) {
188
+ const { workspace, packageDir, packageName, packageFolderName: packageFolderName$ } = devShared.Locals.impl();
189
+ this.packageFolderName = packageFolderName || "";
190
+ this.packageDir = path__namespace.resolve(packageDir, workspace ? `./${packageFolderName}` : "");
191
+ this.packageSourceDir = path__namespace.resolve(packageDir, "./src");
192
+ this.packageName = packageFolderName === packageFolderName$ ? packageName : `${packageName}-${packageFolderName}`;
193
+ this.packageOptions = require$(`${this.packageDir}/package.json`);
194
+ this.commandOptions = commandOptions;
195
+ }
196
+ async process() {
197
+ let start = Date.now();
198
+ const { cwd, workspace } = devShared.Locals.impl();
199
+ const { packageOptions, packageName, packageDir } = this;
200
+ if (workspace && packageOptions?.scripts?.build && packageDir !== cwd) {
201
+ await devShared.Shell.spawn(`npm`, ["run", "build"], {
202
+ cwd: packageDir
203
+ });
204
+ return;
168
205
  }
169
- async buildTypes() {
170
- const { workspace } = devShared.Locals.impl();
171
- const { packageDir, packageOptions } = this;
172
- if (workspace && packageOptions?.scripts?.['build:types']) {
173
- await devShared.Shell.spawn(`npm`, ['run', 'build:types'], {
174
- cwd: packageDir
175
- });
176
- return;
177
- }
178
- const config = path__namespace.resolve(packageDir, `api-extractor.json`);
179
- if (fs.existsSync(config)) {
180
- const result = apiExtractor.Extractor.invoke(apiExtractor.ExtractorConfig.loadFileAndPrepare(config), {
181
- localBuild: true,
182
- showVerboseMessages: false
183
- });
184
- if (!result.succeeded) {
185
- devShared.Logger.error(`API Extractor completed with ${result.errorCount} errors and ${result.warningCount} warnings`);
186
- process.exitCode = 1;
187
- }
188
- }
189
- await fs.remove(`${packageDir}/dist/${workspace || 'src'}`);
206
+ const srcDir = path__namespace.resolve(packageDir, "./src");
207
+ let files = fs.existsSync(srcDir) ? fs.readdirSync(srcDir).filter((i) => /^index(.*)\.(ts|js|s?css)$/.test(i)) : [];
208
+ if (!files.length)
209
+ return;
210
+ const spinner = ora(`${packageName} Build ...`);
211
+ try {
212
+ spinner.start();
213
+ await fs.emptyDir(`${packageDir}/dist`);
214
+ const scriptStats = await run$3(this);
215
+ const scriptDuration = Date.now() - start;
216
+ const styleStats = await run$2(this);
217
+ const styleDuration = Date.now() - start - scriptDuration;
218
+ const typeStats = await run$1(this);
219
+ const typeDuration = Date.now() - start - styleDuration - scriptDuration;
220
+ spinner.stop();
221
+ let message = "";
222
+ message += `${chalk.cyan(`${packageName}`)}: ${chalk.green("Success")} ${chalk.blue(`${Date.now() - start}ms`)}(`;
223
+ message += styleStats.length ? `css: ${chalk.yellow(styleDuration)}ms; ` : "";
224
+ message += scriptStats.length ? `js: ${chalk.yellow(scriptDuration)}ms${typeStats.length ? "; " : ""}` : "";
225
+ message += typeStats.length ? `dts: ${chalk.yellow(typeDuration)}ms` : "";
226
+ message += ")";
227
+ devShared.Logger.log(message);
228
+ scriptStats.concat(styleStats).concat(typeStats).forEach((stat) => {
229
+ let message$ = "";
230
+ message$ += `${chalk.magenta(stat.file)}: `;
231
+ message$ += stat.format ? `${chalk.green(stat.format.toUpperCase())} - ` : "";
232
+ message$ += `${devShared.Utils.formatBytes(stat.size)}`;
233
+ devShared.Logger.log(message$);
234
+ });
235
+ } catch (e) {
236
+ devShared.Logger.log("Error!", e);
237
+ throw e;
190
238
  }
239
+ }
191
240
  }
192
241
  const build = (options, commandOptions) => {
193
- return new Build(options, commandOptions);
242
+ return new Build(options, commandOptions);
194
243
  };
195
244
 
196
245
  const run = (options) => devShared.Utils.autoCatch(async () => {
197
- options = {
198
- formats: 'es,cjs',
199
- ...options
200
- };
201
- const locals = devShared.Locals.impl();
202
- if (typeof options.dryRun === 'undefined') {
203
- options.dryRun = process.env.NODE_ENV === 'UNIT';
204
- }
205
- const { normalizePackageFolderNames } = devShared.Locals.impl();
206
- let packageFolderName = devShared.Locals.getPackageFolderName(options.packageName || '*');
207
- let inputs = [];
208
- if (locals.workspace && packageFolderName === '*') {
209
- inputs = normalizePackageFolderNames;
210
- }
211
- else {
212
- inputs = [packageFolderName];
213
- }
214
- if (options.dryRun)
215
- return devShared.Shell.spawn(`echo ${inputs.join(' ')}`);
216
- await inputs
217
- .reduce((preProcess, packageFolderName$) => {
218
- preProcess = preProcess.then(() => build(packageFolderName$, options).process());
219
- return preProcess;
220
- }, Promise.resolve());
246
+ options = {
247
+ scriptFormats: "es,cjs",
248
+ ...options
249
+ };
250
+ const locals = devShared.Locals.impl();
251
+ if (typeof options.dryRun === "undefined") {
252
+ options.dryRun = process.env.NODE_ENV === "UNIT";
253
+ }
254
+ const { normalizePackageFolderNames } = devShared.Locals.impl();
255
+ let packageFolderName = devShared.Locals.getPackageFolderName(options.packageName || "*");
256
+ let inputs = [];
257
+ if (locals.workspace && packageFolderName === "*") {
258
+ inputs = normalizePackageFolderNames;
259
+ } else {
260
+ inputs = [packageFolderName];
261
+ }
262
+ if (options.dryRun)
263
+ return devShared.Shell.spawn(`echo ${inputs.join(" ")}`);
264
+ await inputs.reduce(
265
+ (preProcess, packageFolderName$) => {
266
+ preProcess = preProcess.then(() => build(packageFolderName$, options).process());
267
+ return preProcess;
268
+ },
269
+ Promise.resolve()
270
+ );
221
271
  }, {
222
- onError: (e) => {
223
- if (typeof e === 'number' && e === 1) {
224
- devShared.Logger.error('编译未通过');
225
- }
226
- else {
227
- devShared.Logger.error(e);
228
- }
229
- process.exit(1);
272
+ onError: (e) => {
273
+ if (typeof e === "number" && e === 1) {
274
+ devShared.Logger.error("编译未通过");
275
+ } else {
276
+ devShared.Logger.error(e);
230
277
  }
278
+ process.exit(1);
279
+ }
231
280
  });
232
281
 
233
282
  exports.run = run;
package/dist/index.es.js CHANGED
@@ -2,211 +2,258 @@ import { Locals, Shell, Logger, Utils } from '@deot/dev-shared';
2
2
  import * as path from 'node:path';
3
3
  import { createRequire } from 'node:module';
4
4
  import fs from 'fs-extra';
5
- import typescript from '@rollup/plugin-typescript';
6
- import { nodeResolve } from '@rollup/plugin-node-resolve';
7
- import commonjs from '@rollup/plugin-commonjs';
8
- import replace from '@rollup/plugin-replace';
9
- import { rollup } from 'rollup';
10
- import { Extractor, ExtractorConfig } from '@microsoft/api-extractor';
11
5
  import chalk from 'chalk';
12
6
  import ora from 'ora';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { build as build$1 } from 'vite';
9
+ import sass from 'sass';
10
+ import postcss from 'postcss';
11
+ import atImport from 'postcss-import';
12
+ import atUrl from 'postcss-url';
13
+ import flexBugs from 'postcss-flexbugs-fixes';
14
+ import cssnano from 'cssnano';
15
+ import autoprefixer from 'autoprefixer';
16
+ import { Extractor, ExtractorConfig } from '@microsoft/api-extractor';
13
17
 
14
- const require$ = createRequire(process.cwd());
15
- class Build {
16
- packageDir;
17
- packageName;
18
- packageOptions;
19
- config;
20
- commandOptions;
21
- constructor(config, commandOptions) {
22
- const { workspace, packageDir, packageName } = Locals.impl();
23
- if (typeof config === 'string') {
24
- let packageFolderName = config;
25
- let packageDir$ = path.resolve(packageDir, packageFolderName);
26
- let input = fs.existsSync(packageDir$ + '/src/index.ts')
27
- ? packageDir$ + '/src/index.ts'
28
- : fs.existsSync(packageDir$ + '/src/index.js')
29
- ? packageDir$ + '/src/index.js'
30
- : '';
31
- config = {
32
- dir: packageDir$,
33
- name: packageFolderName || 'index',
34
- input,
35
- output: [
36
- {
37
- file: packageDir$ + '/dist/index.es.js',
38
- format: 'es',
39
- exports: 'named',
40
- sourcemap: false
41
- },
42
- {
43
- file: packageDir$ + '/dist/index.iife.js',
44
- format: 'iife',
45
- name: packageName,
46
- },
47
- {
48
- file: packageDir$ + '/dist/index.cjs.js',
49
- format: 'cjs'
50
- }
51
- ].filter(i => {
52
- return commandOptions.formats.includes(i.format);
53
- })
54
- };
55
- }
56
- this.packageDir = path.resolve(packageDir, workspace ? `./${config.name}` : '');
57
- this.packageName = config.name === 'index'
58
- ? packageName
59
- : `${packageName}-${config.name}`;
60
- this.packageOptions = require$(`${this.packageDir}/package.json`);
61
- this.config = config;
62
- this.commandOptions = commandOptions;
18
+ const dirname$1 = path.dirname(fileURLToPath(import.meta.url));
19
+ const run$3 = async (options) => {
20
+ const locals = Locals.impl();
21
+ const { cwd } = locals;
22
+ const { packageName, packageDir, packageOptions } = options || {};
23
+ const stats = [];
24
+ const srcDir = path.resolve(packageDir, "./src");
25
+ const outDir = path.resolve(packageDir, "./dist");
26
+ let files = fs.existsSync(srcDir) ? fs.readdirSync(srcDir).filter((i) => /^index(.*)\.(t|j)s$/.test(i)) : [];
27
+ if (!files.length)
28
+ return stats;
29
+ process.env.BUILD_OPTIONS = encodeURIComponent(JSON.stringify({
30
+ files,
31
+ packageName,
32
+ packageDir,
33
+ packageOptions
34
+ }));
35
+ let options$ = {};
36
+ if (fs.existsSync(`${cwd}/build.config.ts`)) {
37
+ options$.configFile = path.relative(cwd, path.resolve(cwd, "./build.config.ts"));
38
+ } else if (fs.existsSync(`${cwd}/z.build.config.ts`)) {
39
+ options$.configFile = path.relative(cwd, path.resolve(cwd, "./z.build.config.ts"));
40
+ } else {
41
+ options$.configFile = path.relative(cwd, path.resolve(dirname$1, "../shared.config.ts"));
42
+ }
43
+ await build$1(options$);
44
+ let outputs = fs.readdirSync(outDir).filter((i) => /^index(.*)(?!=\.d)\.js$/.test(i));
45
+ outputs.forEach((file) => {
46
+ let stat = fs.statSync(path.resolve(outDir, file));
47
+ stats.push({
48
+ file: file.replace(/^(.*)(\..*\.js)/, "$1.ts"),
49
+ format: file.replace(/.*\.(.*)\.js/, "$1"),
50
+ size: stat.size
51
+ });
52
+ });
53
+ return stats;
54
+ };
55
+
56
+ const run$2 = async (options) => {
57
+ const { packageDir } = options || {};
58
+ const srcDir = path.resolve(packageDir, "./src");
59
+ const styles = fs.existsSync(srcDir) ? fs.readdirSync(srcDir).filter((i) => /^index(.*)\.s?css$/.test(i)) : [];
60
+ const stats = [];
61
+ await styles.reduce(
62
+ (preProcess, file) => {
63
+ preProcess = preProcess.then(() => {
64
+ let filepath = path.resolve(srcDir, file);
65
+ const data = sass.compile(filepath, { style: "compressed" });
66
+ return postcss().use(atImport()).use(atUrl()).use(flexBugs()).use(cssnano()).use(autoprefixer({ remove: false })).process(data.css, { from: filepath });
67
+ }).then((source) => {
68
+ let output = path.resolve(packageDir, `./dist/${file.replace(/\.scss$/g, ".css")}`);
69
+ fs.outputFileSync(output, source.css);
70
+ return fs.stat(output);
71
+ }).then((stat) => {
72
+ stats.push({
73
+ file,
74
+ size: stat.size
75
+ });
76
+ });
77
+ return preProcess;
78
+ },
79
+ Promise.resolve()
80
+ );
81
+ return stats;
82
+ };
83
+
84
+ const dirname = path.dirname(fileURLToPath(import.meta.url));
85
+ const run$1 = async (options) => {
86
+ const { workspace } = Locals.impl();
87
+ const { packageDir, packageFolderName, packageOptions, commandOptions } = options;
88
+ const done = () => {
89
+ const stats = [];
90
+ let fullpath = `${packageDir}/dist/index.d.ts`;
91
+ if (fs.existsSync(fullpath)) {
92
+ let stat = fs.statSync(fullpath);
93
+ stats.push({
94
+ file: "index.d.ts",
95
+ size: stat.size
96
+ });
63
97
  }
64
- async process() {
65
- const { cwd, workspace } = Locals.impl();
66
- const { config, packageOptions, packageName, packageDir } = this;
67
- if (workspace
68
- && packageOptions?.scripts?.build
69
- && packageDir !== cwd) {
70
- await Shell.spawn(`npm`, ['run', 'build'], {
71
- cwd: packageDir
72
- });
73
- return;
74
- }
75
- if (!config.input)
76
- return;
77
- const spinner = ora(`${packageName} Build ...`);
78
- try {
79
- spinner.start();
80
- await fs.emptyDir(`${packageDir}/dist`);
81
- const stats = await this.buildSources();
82
- await this.buildTypes();
83
- spinner.stop();
84
- Logger.log(`${chalk.cyan(`${packageName}`)}: ${chalk.green('Success')}`);
85
- stats.forEach((stat) => {
86
- Logger.log(`${chalk.green(stat.format.toUpperCase())}: ${Utils.formatBytes(stat.size)}`);
87
- });
88
- }
89
- catch (e) {
90
- Logger.log('Error!', e);
91
- throw e;
98
+ return stats;
99
+ };
100
+ if (!commandOptions.dts) {
101
+ return done();
102
+ }
103
+ if (workspace && packageOptions?.scripts?.["build:types"]) {
104
+ await Shell.spawn(`npm`, ["run", "build:types"], {
105
+ cwd: packageDir
106
+ });
107
+ return done();
108
+ }
109
+ let tempDir = `${packageDir}/dist/temp`;
110
+ let rootDir = path.relative(tempDir, process.cwd());
111
+ fs.outputFileSync(`${tempDir}/tsconfig.json`, JSON.stringify({
112
+ extends: `${rootDir}/tsconfig.json`,
113
+ compilerOptions: {
114
+ declaration: true,
115
+ emitDeclarationOnly: true,
116
+ rootDir,
117
+ outDir: "."
118
+ },
119
+ include: [
120
+ path.relative(tempDir, path.resolve(packageDir, `src/*`))
121
+ ]
122
+ }, null, " "));
123
+ await Shell.spawn("tsc", ["-p", `${tempDir}/tsconfig.json`]);
124
+ const configPath = `${tempDir}/api-extractor.json`;
125
+ fs.outputFileSync(configPath, JSON.stringify({
126
+ extends: path.relative(tempDir, path.resolve(dirname, "../api-extractor.shared.json")),
127
+ mainEntryPointFilePath: `.${workspace ? "/packages/" : ""}${packageFolderName}/src/index.d.ts`,
128
+ // workspace、时以temp/packages/*/src结构,否则APIExtractor会报错
129
+ dtsRollup: {
130
+ publicTrimmedFilePath: "../index.d.ts"
131
+ }
132
+ }, null, " "));
133
+ const result = Extractor.invoke(
134
+ ExtractorConfig.loadFileAndPrepare(configPath),
135
+ {
136
+ localBuild: true,
137
+ showVerboseMessages: false,
138
+ // 去掉版本提示
139
+ messageCallback: (message) => {
140
+ if (message.messageId === "console-compiler-version-notice" || message.messageId === "console-preamble") {
141
+ message.handled = true;
92
142
  }
143
+ }
93
144
  }
94
- async buildSources() {
95
- const { workspace } = Locals.impl();
96
- const { name, input, output } = this.config;
97
- const { packageOptions } = this;
98
- const external = Object
99
- .keys({
100
- ...packageOptions.dependencies,
101
- ...packageOptions.peerDependencies
102
- })
103
- .map(i => new RegExp(`^${i}$`));
104
- const source = workspace ? `${workspace}/${name}/**/*` : 'src/**/*';
105
- const shims = workspace ? `${workspace}/shims.d.ts` : 'shims.d.ts';
106
- const outDir = workspace ? `${workspace}/${name}/dist` : 'dist';
107
- const builder = await rollup({
108
- input,
109
- external: [
110
- /^node:/,
111
- /^[a-zA-Z@]/,
112
- ...external
113
- ],
114
- plugins: [
115
- typescript({
116
- include: [source, shims],
117
- exclude: ['dist'],
118
- compilerOptions: {
119
- rootDir: '.',
120
- outDir,
121
- declaration: true
122
- }
123
- }),
124
- commonjs({ extensions: ['.js', '.ts'] }),
125
- nodeResolve(),
126
- replace({
127
- '1.1.0': `'${packageOptions.version}'`,
128
- false: 'false',
129
- true: true
130
- })
131
- ]
132
- });
133
- await Promise.all(output.map(builder.write));
134
- const stats = [];
135
- await output.reduce((pre, cur, index) => {
136
- pre
137
- .then(() => fs.stat(cur.file))
138
- .then((stat) => {
139
- stats[index] = {
140
- format: cur.format,
141
- size: stat.size
142
- };
143
- });
144
- return pre;
145
- }, Promise.resolve());
146
- return stats;
145
+ );
146
+ if (!result.succeeded) {
147
+ Logger.error(
148
+ `API Extractor completed with ${result.errorCount} errors and ${result.warningCount} warnings`
149
+ );
150
+ process.exitCode = 1;
151
+ }
152
+ await fs.remove(`${packageDir}/dist/temp`);
153
+ return done();
154
+ };
155
+
156
+ const require$ = createRequire(process.cwd());
157
+ class Build {
158
+ packageDir;
159
+ packageFolderName;
160
+ packageSourceDir;
161
+ packageName;
162
+ packageOptions;
163
+ commandOptions;
164
+ constructor(packageFolderName, commandOptions) {
165
+ const { workspace, packageDir, packageName, packageFolderName: packageFolderName$ } = Locals.impl();
166
+ this.packageFolderName = packageFolderName || "";
167
+ this.packageDir = path.resolve(packageDir, workspace ? `./${packageFolderName}` : "");
168
+ this.packageSourceDir = path.resolve(packageDir, "./src");
169
+ this.packageName = packageFolderName === packageFolderName$ ? packageName : `${packageName}-${packageFolderName}`;
170
+ this.packageOptions = require$(`${this.packageDir}/package.json`);
171
+ this.commandOptions = commandOptions;
172
+ }
173
+ async process() {
174
+ let start = Date.now();
175
+ const { cwd, workspace } = Locals.impl();
176
+ const { packageOptions, packageName, packageDir } = this;
177
+ if (workspace && packageOptions?.scripts?.build && packageDir !== cwd) {
178
+ await Shell.spawn(`npm`, ["run", "build"], {
179
+ cwd: packageDir
180
+ });
181
+ return;
147
182
  }
148
- async buildTypes() {
149
- const { workspace } = Locals.impl();
150
- const { packageDir, packageOptions } = this;
151
- if (workspace && packageOptions?.scripts?.['build:types']) {
152
- await Shell.spawn(`npm`, ['run', 'build:types'], {
153
- cwd: packageDir
154
- });
155
- return;
156
- }
157
- const config = path.resolve(packageDir, `api-extractor.json`);
158
- if (fs.existsSync(config)) {
159
- const result = Extractor.invoke(ExtractorConfig.loadFileAndPrepare(config), {
160
- localBuild: true,
161
- showVerboseMessages: false
162
- });
163
- if (!result.succeeded) {
164
- Logger.error(`API Extractor completed with ${result.errorCount} errors and ${result.warningCount} warnings`);
165
- process.exitCode = 1;
166
- }
167
- }
168
- await fs.remove(`${packageDir}/dist/${workspace || 'src'}`);
183
+ const srcDir = path.resolve(packageDir, "./src");
184
+ let files = fs.existsSync(srcDir) ? fs.readdirSync(srcDir).filter((i) => /^index(.*)\.(ts|js|s?css)$/.test(i)) : [];
185
+ if (!files.length)
186
+ return;
187
+ const spinner = ora(`${packageName} Build ...`);
188
+ try {
189
+ spinner.start();
190
+ await fs.emptyDir(`${packageDir}/dist`);
191
+ const scriptStats = await run$3(this);
192
+ const scriptDuration = Date.now() - start;
193
+ const styleStats = await run$2(this);
194
+ const styleDuration = Date.now() - start - scriptDuration;
195
+ const typeStats = await run$1(this);
196
+ const typeDuration = Date.now() - start - styleDuration - scriptDuration;
197
+ spinner.stop();
198
+ let message = "";
199
+ message += `${chalk.cyan(`${packageName}`)}: ${chalk.green("Success")} ${chalk.blue(`${Date.now() - start}ms`)}(`;
200
+ message += styleStats.length ? `css: ${chalk.yellow(styleDuration)}ms; ` : "";
201
+ message += scriptStats.length ? `js: ${chalk.yellow(scriptDuration)}ms${typeStats.length ? "; " : ""}` : "";
202
+ message += typeStats.length ? `dts: ${chalk.yellow(typeDuration)}ms` : "";
203
+ message += ")";
204
+ Logger.log(message);
205
+ scriptStats.concat(styleStats).concat(typeStats).forEach((stat) => {
206
+ let message$ = "";
207
+ message$ += `${chalk.magenta(stat.file)}: `;
208
+ message$ += stat.format ? `${chalk.green(stat.format.toUpperCase())} - ` : "";
209
+ message$ += `${Utils.formatBytes(stat.size)}`;
210
+ Logger.log(message$);
211
+ });
212
+ } catch (e) {
213
+ Logger.log("Error!", e);
214
+ throw e;
169
215
  }
216
+ }
170
217
  }
171
218
  const build = (options, commandOptions) => {
172
- return new Build(options, commandOptions);
219
+ return new Build(options, commandOptions);
173
220
  };
174
221
 
175
222
  const run = (options) => Utils.autoCatch(async () => {
176
- options = {
177
- formats: 'es,cjs',
178
- ...options
179
- };
180
- const locals = Locals.impl();
181
- if (typeof options.dryRun === 'undefined') {
182
- options.dryRun = process.env.NODE_ENV === 'UNIT';
183
- }
184
- const { normalizePackageFolderNames } = Locals.impl();
185
- let packageFolderName = Locals.getPackageFolderName(options.packageName || '*');
186
- let inputs = [];
187
- if (locals.workspace && packageFolderName === '*') {
188
- inputs = normalizePackageFolderNames;
189
- }
190
- else {
191
- inputs = [packageFolderName];
192
- }
193
- if (options.dryRun)
194
- return Shell.spawn(`echo ${inputs.join(' ')}`);
195
- await inputs
196
- .reduce((preProcess, packageFolderName$) => {
197
- preProcess = preProcess.then(() => build(packageFolderName$, options).process());
198
- return preProcess;
199
- }, Promise.resolve());
223
+ options = {
224
+ scriptFormats: "es,cjs",
225
+ ...options
226
+ };
227
+ const locals = Locals.impl();
228
+ if (typeof options.dryRun === "undefined") {
229
+ options.dryRun = process.env.NODE_ENV === "UNIT";
230
+ }
231
+ const { normalizePackageFolderNames } = Locals.impl();
232
+ let packageFolderName = Locals.getPackageFolderName(options.packageName || "*");
233
+ let inputs = [];
234
+ if (locals.workspace && packageFolderName === "*") {
235
+ inputs = normalizePackageFolderNames;
236
+ } else {
237
+ inputs = [packageFolderName];
238
+ }
239
+ if (options.dryRun)
240
+ return Shell.spawn(`echo ${inputs.join(" ")}`);
241
+ await inputs.reduce(
242
+ (preProcess, packageFolderName$) => {
243
+ preProcess = preProcess.then(() => build(packageFolderName$, options).process());
244
+ return preProcess;
245
+ },
246
+ Promise.resolve()
247
+ );
200
248
  }, {
201
- onError: (e) => {
202
- if (typeof e === 'number' && e === 1) {
203
- Logger.error('编译未通过');
204
- }
205
- else {
206
- Logger.error(e);
207
- }
208
- process.exit(1);
249
+ onError: (e) => {
250
+ if (typeof e === "number" && e === 1) {
251
+ Logger.error("编译未通过");
252
+ } else {
253
+ Logger.error(e);
209
254
  }
255
+ process.exit(1);
256
+ }
210
257
  });
211
258
 
212
259
  export { run };
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@deot/dev-builder",
3
- "version": "1.1.1",
3
+ "version": "2.0.0",
4
4
  "main": "dist/index.es.js",
5
5
  "module": "dist/index.es.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "files": [
9
- "dist"
9
+ "dist",
10
+ "api-extractor.shared.json"
10
11
  ],
11
12
  "license": "MIT",
12
13
  "publishConfig": {
@@ -21,18 +22,21 @@
21
22
  }
22
23
  },
23
24
  "dependencies": {
24
- "@deot/dev-shared": "^1.1.1",
25
- "@microsoft/api-extractor": "^7.34.4",
26
- "@rollup/plugin-commonjs": "^24.1.0",
27
- "@rollup/plugin-node-resolve": "^15.0.2",
28
- "@rollup/plugin-replace": "^5.0.2",
29
- "@rollup/plugin-typescript": "^11.1.0",
25
+ "@deot/dev-shared": "^2.0.0",
26
+ "@microsoft/api-extractor": "^7.35.1",
27
+ "autoprefixer": "^10.4.14",
30
28
  "chalk": "^5.2.0",
29
+ "cssnano": "^5.1.15",
31
30
  "fs-extra": "^11.1.1",
32
31
  "ora": "^6.1.2",
33
- "rollup": "^3.20.5"
32
+ "postcss": "^8.4.24",
33
+ "postcss-flexbugs-fixes": "^5.0.2",
34
+ "postcss-import": "^15.1.0",
35
+ "postcss-url": "^10.1.3",
36
+ "sass": "^1.62.1",
37
+ "vite": "^4.3.9"
34
38
  },
35
39
  "devDependencies": {
36
- "typescript": "^5.0.4"
40
+ "typescript": "^5.1.3"
37
41
  }
38
42
  }