@liuli-util/cli 3.21.0 → 3.22.1

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 (67) hide show
  1. package/bin.js +1 -1
  2. package/dist/bin.js +152 -106
  3. package/dist/bin.js.map +3 -3
  4. package/dist/commands/deploy/util/execPromise.d.ts +1 -0
  5. package/dist/commands/deploy/util/execPromise.d.ts.map +1 -1
  6. package/dist/commands/esbuild/ESBuildProgram.d.ts +0 -6
  7. package/dist/commands/esbuild/ESBuildProgram.d.ts.map +1 -1
  8. package/dist/commands/esbuild/util/autoExternal.d.ts +7 -0
  9. package/dist/commands/esbuild/util/autoExternal.d.ts.map +1 -0
  10. package/dist/commands/esbuild/util/env.d.ts +16 -0
  11. package/dist/commands/esbuild/util/env.d.ts.map +1 -0
  12. package/dist/commands/esbuild/util/index.d.ts +11 -0
  13. package/dist/commands/esbuild/util/index.d.ts.map +1 -0
  14. package/dist/commands/esbuild/util/log.d.ts +3 -0
  15. package/dist/commands/esbuild/util/log.d.ts.map +1 -0
  16. package/dist/commands/esbuild/util/metafile.d.ts +7 -0
  17. package/dist/commands/esbuild/util/metafile.d.ts.map +1 -0
  18. package/dist/commands/esbuild/util/nativeNodeModules.d.ts +7 -0
  19. package/dist/commands/esbuild/util/nativeNodeModules.d.ts.map +1 -0
  20. package/dist/commands/esbuild/util/nodeExternal.d.ts +6 -0
  21. package/dist/commands/esbuild/util/nodeExternal.d.ts.map +1 -0
  22. package/dist/commands/esbuild/util/raw.d.ts +7 -0
  23. package/dist/commands/esbuild/util/raw.d.ts.map +1 -0
  24. package/dist/commands/esbuild/util/resolve.d.ts +8 -0
  25. package/dist/commands/esbuild/util/resolve.d.ts.map +1 -0
  26. package/dist/commands/esbuild/util/sideEffect.d.ts +8 -0
  27. package/dist/commands/esbuild/util/sideEffect.d.ts.map +1 -0
  28. package/dist/commands/esbuild/util/userJS.d.ts +3 -0
  29. package/dist/commands/esbuild/util/userJS.d.ts.map +1 -0
  30. package/dist/index.esm.js +3 -3
  31. package/dist/index.esm.js.map +3 -3
  32. package/dist/index.js +3 -3
  33. package/dist/index.js.map +3 -3
  34. package/package.json +40 -36
  35. package/src/commands/esbuild/ESBuildProgram.ts +5 -9
  36. package/src/commands/esbuild/__tests__/ESBuildProgram.test.ts +2 -2
  37. package/src/commands/esbuild/util/autoExternal.ts +22 -0
  38. package/src/commands/esbuild/util/env.ts +67 -0
  39. package/src/commands/esbuild/util/index.ts +10 -0
  40. package/src/commands/esbuild/util/log.ts +20 -0
  41. package/src/commands/esbuild/util/metafile.ts +17 -0
  42. package/src/commands/esbuild/util/nativeNodeModules.ts +43 -0
  43. package/src/commands/esbuild/util/nodeExternal.ts +16 -0
  44. package/src/commands/esbuild/util/raw.ts +27 -0
  45. package/src/commands/esbuild/util/resolve.ts +22 -0
  46. package/src/commands/esbuild/util/sideEffect.ts +29 -0
  47. package/src/commands/esbuild/util/userJS.ts +38 -0
  48. package/templates/cli/package.json +35 -33
  49. package/templates/lib/package.json +24 -19
  50. package/dist/commands/esbuild/util/esbuildPlugins.d.ts +0 -32
  51. package/dist/commands/esbuild/util/esbuildPlugins.d.ts.map +0 -1
  52. package/src/commands/esbuild/__tests__/.temp/package.json +0 -1
  53. package/src/commands/esbuild/__tests__/.temp/src/index.ts +0 -1
  54. package/src/commands/esbuild/util/__tests__/.temp/index.js +0 -1
  55. package/src/commands/esbuild/util/__tests__/esbuildPlugins.test.ts +0 -52
  56. package/src/commands/esbuild/util/esbuildPlugins.ts +0 -196
  57. package/src/commands/generate/__tests__/.temp/README.md +0 -1
  58. package/src/commands/generate/__tests__/.temp/package.json +0 -3
  59. package/src/commands/generate/__tests__/.temp/test-cli/CHANGELOG.md +0 -1
  60. package/src/commands/generate/__tests__/.temp/test-cli/README.md +0 -1
  61. package/src/commands/generate/__tests__/.temp/test-cli/bin.js +0 -3
  62. package/src/commands/generate/__tests__/.temp/test-cli/package.json +0 -33
  63. package/src/commands/generate/__tests__/.temp/test-cli/src/bin.ts +0 -13
  64. package/src/commands/generate/__tests__/.temp/test-cli/src/index.ts +0 -1
  65. package/src/commands/generate/__tests__/.temp/test-cli/tsconfig.json +0 -28
  66. package/src/commands/sync/__tests__/.temp/package.json +0 -16
  67. package/wallaby.conf.js +0 -3
@@ -0,0 +1,67 @@
1
+ import { Plugin } from 'esbuild'
2
+
3
+ /**
4
+ * @param {string} str
5
+ */
6
+ function isValidId(str: string) {
7
+ try {
8
+ new Function(`var ${str};`)
9
+ } catch (err) {
10
+ return false
11
+ }
12
+ return true
13
+ }
14
+
15
+ /**
16
+ * Create a map of replacements for environment variables.
17
+ * @return A map of variables.
18
+ */
19
+ export function defineProcessEnv() {
20
+ /**
21
+ * @type {{ [key: string]: string }}
22
+ */
23
+ const definitions: Record<string, string> = {}
24
+ definitions['process.env.NODE_ENV'] = JSON.stringify(process.env.NODE_ENV || 'development')
25
+ Object.keys(process.env).forEach((key) => {
26
+ if (isValidId(key)) {
27
+ definitions[`process.env.${key}`] = JSON.stringify(process.env[key])
28
+ }
29
+ })
30
+ definitions['process.env'] = '{}'
31
+
32
+ return definitions
33
+ }
34
+
35
+ export function defineImportEnv() {
36
+ const definitions: Record<string, string> = {}
37
+ Object.keys(process.env).forEach((key) => {
38
+ if (isValidId(key)) {
39
+ definitions[`import.meta.env.${key}`] = JSON.stringify(process.env[key])
40
+ }
41
+ })
42
+ definitions['import.meta.env'] = '{}'
43
+ return definitions
44
+ }
45
+
46
+ /**
47
+ * Pass environment variables to esbuild.
48
+ * @return An esbuild plugin.
49
+ */
50
+ export function env(options: { process?: boolean; import?: boolean }): Plugin {
51
+ return {
52
+ name: 'env',
53
+ setup(build) {
54
+ const { platform, define = {} } = build.initialOptions
55
+ if (platform === 'node') {
56
+ return
57
+ }
58
+ build.initialOptions.define = define
59
+ if (options.import) {
60
+ Object.assign(build.initialOptions.define, defineImportEnv())
61
+ }
62
+ if (options.process) {
63
+ Object.assign(build.initialOptions.define, defineProcessEnv())
64
+ }
65
+ },
66
+ }
67
+ }
@@ -0,0 +1,10 @@
1
+ export * from './autoExternal'
2
+ export * from './env'
3
+ export * from './log'
4
+ export * from './metafile'
5
+ export * from './nativeNodeModules'
6
+ export * from './nodeExternal'
7
+ export * from './raw'
8
+ export * from './resolve'
9
+ export * from './sideEffect'
10
+ export * from './userJS'
@@ -0,0 +1,20 @@
1
+ import { Plugin, PluginBuild } from 'esbuild'
2
+
3
+ export function log(): Plugin {
4
+ return {
5
+ name: 'log',
6
+ setup(builder: PluginBuild) {
7
+ let start: number
8
+ builder.onStart(() => {
9
+ start = Date.now()
10
+ })
11
+ builder.onEnd((result) => {
12
+ if (result.errors.length !== 0) {
13
+ console.error('build failed', result.errors)
14
+ return
15
+ }
16
+ console.log(`build complete, time ${Date.now() - start}ms`)
17
+ })
18
+ },
19
+ }
20
+ }
@@ -0,0 +1,17 @@
1
+ import { Plugin } from 'esbuild'
2
+ import { writeJson } from 'fs-extra'
3
+
4
+ /**
5
+ * 生成 metafile 的插件
6
+ * @param metafilePath
7
+ */
8
+ export function metafile(metafilePath: string): Plugin {
9
+ return {
10
+ name: 'metafile',
11
+ setup(builder) {
12
+ builder.onEnd(async (result) => {
13
+ await writeJson(metafilePath, result.metafile)
14
+ })
15
+ },
16
+ }
17
+ }
@@ -0,0 +1,43 @@
1
+ import { Plugin } from 'esbuild'
2
+
3
+ /**
4
+ * 处理 nodejs 原生模块
5
+ * @link https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487
6
+ */
7
+ export function nativeNodeModules(): Plugin {
8
+ return {
9
+ name: 'native-node-modules',
10
+ setup(build) {
11
+ // If a ".node" file is imported within a module in the "file" namespace, resolve
12
+ // it to an absolute path and put it into the "node-file" virtual namespace.
13
+ build.onResolve({ filter: /\.node$/, namespace: 'file' }, (args) => ({
14
+ path: require.resolve(args.path, { paths: [args.resolveDir] }),
15
+ namespace: 'node-file',
16
+ }))
17
+
18
+ // Files in the "node-file" virtual namespace call "require()" on the
19
+ // path from esbuild of the ".node" file in the output directory.
20
+ build.onLoad({ filter: /.*/, namespace: 'node-file' }, (args) => ({
21
+ contents: `
22
+ import path from ${JSON.stringify(args.path)}
23
+ try { module.exports = require(path) }
24
+ catch {}
25
+ `,
26
+ }))
27
+
28
+ // If a ".node" file is imported within a module in the "node-file" namespace, put
29
+ // it in the "file" namespace where esbuild's default loading behavior will handle
30
+ // it. It is already an absolute path since we resolved it to one above.
31
+ build.onResolve({ filter: /\.node$/, namespace: 'node-file' }, (args) => ({
32
+ path: args.path,
33
+ namespace: 'file',
34
+ }))
35
+
36
+ // Tell esbuild's default loading behavior to use the "file" loader for
37
+ // these ".node" files.
38
+ const opts = build.initialOptions
39
+ opts.loader = opts.loader || {}
40
+ opts.loader['.node'] = 'file'
41
+ },
42
+ }
43
+ }
@@ -0,0 +1,16 @@
1
+ import { Plugin } from 'esbuild'
2
+
3
+ /**
4
+ * 排除和替换 node 内置模块
5
+ */
6
+ export function nodeExternal(): Plugin {
7
+ return {
8
+ name: 'nodeExternals',
9
+ setup(build) {
10
+ build.onResolve({ filter: /(^node:)/ }, (args) => ({
11
+ path: args.path.slice(5),
12
+ external: true,
13
+ }))
14
+ },
15
+ }
16
+ }
@@ -0,0 +1,27 @@
1
+ import { Plugin } from 'esbuild'
2
+ import { readFile } from 'fs-extra'
3
+ import * as path from 'path'
4
+
5
+ /**
6
+ * 通过 ?raw 将资源作为字符串打包进来
7
+ * @returns
8
+ */
9
+ export function raw(): Plugin {
10
+ return {
11
+ name: 'raw',
12
+ setup(build) {
13
+ build.onResolve({ filter: /\?raw$/ }, (args) => {
14
+ return {
15
+ path: path.isAbsolute(args.path) ? args.path : path.join(args.resolveDir, args.path),
16
+ namespace: 'raw-loader',
17
+ }
18
+ })
19
+ build.onLoad({ filter: /\?raw$/, namespace: 'raw-loader' }, async (args) => {
20
+ return {
21
+ contents: await readFile(args.path.replace(/\?raw$/, '')),
22
+ loader: 'text',
23
+ }
24
+ })
25
+ },
26
+ }
27
+ }
@@ -0,0 +1,22 @@
1
+ import { build, Plugin } from 'esbuild'
2
+ import path from 'path'
3
+
4
+ /**
5
+ * 将指定的 import 重写为另一个
6
+ * @param entries
7
+ * @returns
8
+ */
9
+ export function resolve(entries: [from: string, to: string][]): Plugin {
10
+ return {
11
+ name: 'resolve',
12
+ setup(build) {
13
+ build.onResolve({ filter: /.*/ }, async (args) => {
14
+ const findEntries = entries.find((item) => item[0] === args.path)
15
+ if (!findEntries) {
16
+ return
17
+ }
18
+ return await build.resolve(findEntries[1])
19
+ })
20
+ },
21
+ }
22
+ }
@@ -0,0 +1,29 @@
1
+ import { Plugin } from 'esbuild'
2
+
3
+ /**
4
+ * 设置指定模块为没有副作用的包,由于 webpack/esbuild 的配置不兼容,所以先使用插件来完成这件事
5
+ * @param packages
6
+ * @returns
7
+ */
8
+ export function sideEffects(packages: string[]): Plugin {
9
+ return {
10
+ name: 'sideEffects',
11
+ setup(build) {
12
+ build.onResolve({ filter: /.*/ }, async (args) => {
13
+ if (
14
+ args.pluginData || // Ignore this if we called ourselves
15
+ !packages.includes(args.path)
16
+ ) {
17
+ return
18
+ }
19
+
20
+ const { path, ...rest } = args
21
+ rest.pluginData = true // Avoid infinite recursion
22
+ const result = await build.resolve(path, rest)
23
+
24
+ result.sideEffects = false
25
+ return result
26
+ })
27
+ },
28
+ }
29
+ }
@@ -0,0 +1,38 @@
1
+ import { Plugin } from 'esbuild'
2
+ import { readJson } from 'fs-extra'
3
+ import path from 'path'
4
+
5
+ function generateBanner(meta: object) {
6
+ return (
7
+ [
8
+ '// ==UserScript==',
9
+ ...Object.entries(meta)
10
+ .map(([key, value]) => {
11
+ if (Array.isArray(value)) {
12
+ return value.map((item) => `// @${key} ${item}`)
13
+ }
14
+ return `// @${key} ${value}`
15
+ })
16
+ .flat(),
17
+ '// ==/UserScript==',
18
+ ].join('\n') + '\n'
19
+ )
20
+ }
21
+
22
+ export function userJS(): Plugin {
23
+ return {
24
+ name: 'userJS',
25
+ async setup(build) {
26
+ const json = (await readJson(path.resolve(build.initialOptions.absWorkingDir!, 'package.json'))) as {
27
+ userjs: object
28
+ }
29
+ if (!json.userjs) {
30
+ throw new Error('userjs is not supported')
31
+ }
32
+ if (!build.initialOptions.banner) {
33
+ build.initialOptions.banner = {}
34
+ }
35
+ build.initialOptions.banner!['js'] = generateBanner(json.userjs)
36
+ },
37
+ }
38
+ }
@@ -1,33 +1,35 @@
1
- {
2
- "name": "@liuli-util/cli-template",
3
- "version": "0.1.0",
4
- "main": "dist/index.js",
5
- "module": "dist/index.esm.js",
6
- "types": "dist/index.d.ts",
7
- "license": "MIT",
8
- "scripts": {
9
- "build": "liuli-cli build cli",
10
- "dev": "liuli-cli build cli -w",
11
- "start": "esno src/bin.ts"
12
- },
13
- "bin": {
14
- "cli-name": "./bin.js"
15
- },
16
- "dependencies": {
17
- "commander": "^8.2.0",
18
- "enquirer": "^2.3.6",
19
- "fs-extra": "^10.0.0"
20
- },
21
- "devDependencies": {
22
- "@liuli-util/cli": "^3.18.0",
23
- "@types/fs-extra": "^9.0.13",
24
- "@types/jest": "^27.0.2",
25
- "@types/node": "^16.9.6",
26
- "esno": "^0.9.1",
27
- "jest": "^27.4.7",
28
- "rimraf": "^3.0.2",
29
- "ts-jest": "^27.1.3",
30
- "type-fest": "^2.3.4",
31
- "typescript": "^4.5.5"
32
- }
33
- }
1
+ {
2
+ "name": "@liuli-util/cli-template",
3
+ "version": "0.2.0",
4
+ "main": "./dist/index.js",
5
+ "module": "./dist/index.esm.js",
6
+ "types": "./dist/index.d.ts",
7
+ "license": "MIT",
8
+ "scripts": {
9
+ "build": "liuli-cli build cli",
10
+ "dev": "liuli-cli build cli -w",
11
+ "start": "esno src/bin.ts"
12
+ },
13
+ "bin": {
14
+ "cli-name": "./bin.js"
15
+ },
16
+ "dependencies": {
17
+ "commander": "^9.4.0",
18
+ "enquirer": "^2.3.6",
19
+ "fs-extra": "^10.1.0"
20
+ },
21
+ "devDependencies": {
22
+ "@liuli-util/cli": "workspace:^3.21.0",
23
+ "@types/fs-extra": "^9.0.13",
24
+ "@types/node": "^18.6.4",
25
+ "esno": "^0.16.3",
26
+ "rimraf": "^3.0.2",
27
+ "type-fest": "^2.18.0",
28
+ "typescript": "^4.7.4"
29
+ },
30
+ "exports": {
31
+ "import": "./dist/index.esm.js",
32
+ "require": "./dist/index.js",
33
+ "types": "./dist/index.d.ts"
34
+ }
35
+ }
@@ -1,19 +1,24 @@
1
- {
2
- "name": "@liuli-util/lib-template",
3
- "private": true,
4
- "version": "0.1.0",
5
- "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
7
- "types": "dist/index.d.ts",
8
- "license": "MIT",
9
- "scripts": {
10
- "build": "liuli-cli build lib",
11
- "dev": "liuli-cli build lib -w"
12
- },
13
- "devDependencies": {
14
- "@liuli-util/cli": "^3.18.0",
15
- "rimraf": "^3.0.2",
16
- "type-fest": "^2.3.4",
17
- "typescript": "^4.5.5"
18
- }
19
- }
1
+ {
2
+ "name": "@liuli-util/lib-template",
3
+ "private": true,
4
+ "version": "0.2.0",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.esm.js",
7
+ "types": "./dist/index.d.ts",
8
+ "license": "MIT",
9
+ "scripts": {
10
+ "build": "liuli-cli build lib",
11
+ "dev": "liuli-cli build lib -w"
12
+ },
13
+ "devDependencies": {
14
+ "@liuli-util/cli": "workspace:^3.21.0",
15
+ "rimraf": "^3.0.2",
16
+ "type-fest": "^2.18.0",
17
+ "typescript": "^4.7.4"
18
+ },
19
+ "exports": {
20
+ "import": "./dist/index.esm.js",
21
+ "require": "./dist/index.js",
22
+ "types": "./dist/index.d.ts"
23
+ }
24
+ }
@@ -1,32 +0,0 @@
1
- import { Plugin } from 'esbuild';
2
- /**
3
- * 处理 nodejs 原生模块
4
- * @link https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487
5
- */
6
- export declare function nativeNodeModules(): Plugin;
7
- /**
8
- * 排除和替换 node 内置模块
9
- */
10
- export declare function nodeExternals(): Plugin;
11
- /**
12
- * 自动排除所有依赖项
13
- * golang 不支持 js 的一些语法,参考 https://github.com/evanw/esbuild/issues/1634
14
- */
15
- export declare function autoExternal(): Plugin;
16
- /**
17
- * 通过 ?raw 将资源作为字符串打包进来
18
- * @returns
19
- */
20
- export declare function raw(): Plugin;
21
- /**
22
- * Pass environment variables to esbuild.
23
- * @return An esbuild plugin.
24
- */
25
- export declare function envPlugin(): Plugin;
26
- /**
27
- * 生成 metafile 的插件
28
- * @param metafilePath
29
- */
30
- export declare function metafile(metafilePath: string): Plugin;
31
- export declare function userJS(): Plugin;
32
- //# sourceMappingURL=esbuildPlugins.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"esbuildPlugins.d.ts","sourceRoot":"","sources":["../../../../src/commands/esbuild/util/esbuildPlugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAIhC;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAoC1C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAUtC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAerC;AAED;;;GAGG;AACH,wBAAgB,GAAG,IAAI,MAAM,CAkB5B;AAyBD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAYlC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CASrD;AAmBD,wBAAgB,MAAM,IAAI,MAAM,CAgB/B"}
@@ -1 +0,0 @@
1
- {"name":"test","version":"1.0.0","userjs":{"name":"test","version":"0.1.0","description":"测试脚本","author":"rxliuli","match":["https://twitter.com/*"],"grant":["unsafeWindow"],"license":"MIT"}}
@@ -1 +0,0 @@
1
- console.log(unsafeWindow)
@@ -1 +0,0 @@
1
- console.log(import.meta.env.NODE_ENV)
@@ -1,52 +0,0 @@
1
- import { build, BuildOptions } from 'esbuild'
2
- import { remove, mkdirp, writeFile } from 'fs-extra'
3
- import * as path from 'path'
4
- import { envPlugin as env, raw } from '../esbuildPlugins'
5
-
6
- describe('测试 esbuildPlugins', () => {
7
- const tempPath = path.resolve(__dirname, '.temp')
8
- beforeEach(async () => {
9
- await remove(tempPath)
10
- await mkdirp(tempPath)
11
- })
12
- const options: BuildOptions = {
13
- entryPoints: [path.resolve(tempPath)],
14
- bundle: true,
15
- outfile: path.resolve(tempPath, 'bundle.js'),
16
- format: 'esm',
17
- write: false,
18
- }
19
- describe('测试 raw', () => {
20
- beforeEach(async () => {
21
- await writeFile(path.resolve(tempPath, 'readme.md'), `test`)
22
- await writeFile(
23
- path.resolve(tempPath, 'index.js'),
24
- `
25
- import readme from './readme.md?raw'
26
- console.log(readme)
27
- `,
28
- )
29
- })
30
- it('基本示例', async () => {
31
- const res = await build({ ...options, plugins: [raw()] })
32
- expect(res.outputFiles![0].text.includes(JSON.stringify('test'))).toBeTruthy()
33
- })
34
- it('测试不使用插件', async () => {
35
- await expect(build(options)).rejects.toThrowError()
36
- })
37
- })
38
-
39
- describe('测试 env', () => {
40
- beforeEach(async () => {
41
- await writeFile(path.resolve(tempPath, 'index.js'), `console.log(import.meta.env.NODE_ENV)`)
42
- })
43
- it('基本示例', async () => {
44
- const res = await build({ ...options, plugins: [env()] })
45
- expect(res.outputFiles![0].text.includes('"test"')).toBeTruthy()
46
- })
47
- it('测试不使用插件', async () => {
48
- const res = await build({ ...options })
49
- expect(res.outputFiles![0].text.includes('"test"')).toBeFalsy()
50
- })
51
- })
52
- })