@deot/dev-builder 1.1.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 ADDED
@@ -0,0 +1,14 @@
1
+ # @deot/dev-builder
2
+
3
+ 打包
4
+
5
+ - 使用`dependencies`,非`peerDependencies`。主要考虑仅安装`@deot/dev-builder`即可
6
+ - 优先执行`scripts`下的`build`和`build:types`,如果声明`build`,打包由用户管理,`build:types`,类型编译由用户管理
7
+
8
+
9
+ ## 其它
10
+
11
+ - 目前依赖`rollup`打包,后续考虑读取`rollup.config.js`
12
+ - 如果改成`vite`打包,则考虑读取配置`vite.config.js`
13
+
14
+ 打包输出文件`index.[format].js` + `index.d.ts`
@@ -0,0 +1,233 @@
1
+ 'use strict';
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');
15
+
16
+ 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);
31
+ }
32
+
33
+ var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
34
+
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;
84
+ }
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;
113
+ }
114
+ }
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.0.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
+ 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'}`);
190
+ }
191
+ }
192
+ const build = (options, commandOptions) => {
193
+ return new Build(options, commandOptions);
194
+ };
195
+
196
+ 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());
221
+ }, {
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);
230
+ }
231
+ });
232
+
233
+ exports.run = run;
@@ -0,0 +1,5 @@
1
+ import type { Options } from '@deot/dev-shared';
2
+
3
+ export declare const run: (options: Options) => Promise<any>;
4
+
5
+ export { }
@@ -0,0 +1,212 @@
1
+ import { Locals, Shell, Logger, Utils } from '@deot/dev-shared';
2
+ import * as path from 'node:path';
3
+ import { createRequire } from 'node:module';
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
+ import chalk from 'chalk';
12
+ import ora from 'ora';
13
+
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;
63
+ }
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;
92
+ }
93
+ }
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.0.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;
147
+ }
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'}`);
169
+ }
170
+ }
171
+ const build = (options, commandOptions) => {
172
+ return new Build(options, commandOptions);
173
+ };
174
+
175
+ 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());
200
+ }, {
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);
209
+ }
210
+ });
211
+
212
+ export { run };
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@deot/dev-builder",
3
+ "version": "1.1.0",
4
+ "main": "dist/index.es.js",
5
+ "module": "dist/index.es.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "license": "MIT",
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "dependencies": {
16
+ "@deot/dev-extract": "^1.1.0",
17
+ "@deot/dev-shared": "^1.1.0",
18
+ "@microsoft/api-extractor": "^7.34.4",
19
+ "@rollup/plugin-commonjs": "^24.1.0",
20
+ "@rollup/plugin-node-resolve": "^15.0.2",
21
+ "@rollup/plugin-replace": "^5.0.2",
22
+ "@rollup/plugin-typescript": "11.1.0",
23
+ "rollup": "^3.20.5"
24
+ }
25
+ }