@liuli-util/cli 3.21.0 → 3.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. package/package.json +40 -36
  2. package/src/commands/esbuild/ESBuildProgram.ts +5 -9
  3. package/src/commands/esbuild/__tests__/ESBuildProgram.test.ts +2 -2
  4. package/src/commands/esbuild/util/autoExternal.ts +22 -0
  5. package/src/commands/esbuild/util/env.ts +67 -0
  6. package/src/commands/esbuild/util/index.ts +10 -0
  7. package/src/commands/esbuild/util/log.ts +20 -0
  8. package/src/commands/esbuild/util/metafile.ts +17 -0
  9. package/src/commands/esbuild/util/nativeNodeModules.ts +43 -0
  10. package/src/commands/esbuild/util/nodeExternal.ts +16 -0
  11. package/src/commands/esbuild/util/raw.ts +27 -0
  12. package/src/commands/esbuild/util/resolve.ts +22 -0
  13. package/src/commands/esbuild/util/sideEffect.ts +29 -0
  14. package/src/commands/esbuild/util/userJS.ts +38 -0
  15. package/templates/cli/package.json +35 -33
  16. package/templates/lib/package.json +24 -19
  17. package/dist/PathUtil.d.ts +0 -7
  18. package/dist/PathUtil.d.ts.map +0 -1
  19. package/dist/bin.d.ts +0 -2
  20. package/dist/bin.d.ts.map +0 -1
  21. package/dist/bin.js +0 -171
  22. package/dist/bin.js.map +0 -7
  23. package/dist/commands/deploy/DeployService.d.ts +0 -74
  24. package/dist/commands/deploy/DeployService.d.ts.map +0 -1
  25. package/dist/commands/deploy/deploy.d.ts +0 -3
  26. package/dist/commands/deploy/deploy.d.ts.map +0 -1
  27. package/dist/commands/deploy/index.d.ts +0 -3
  28. package/dist/commands/deploy/index.d.ts.map +0 -1
  29. package/dist/commands/deploy/util/PromiseUtil.d.ts +0 -14
  30. package/dist/commands/deploy/util/PromiseUtil.d.ts.map +0 -1
  31. package/dist/commands/deploy/util/createArchive.d.ts +0 -10
  32. package/dist/commands/deploy/util/createArchive.d.ts.map +0 -1
  33. package/dist/commands/deploy/util/execPromise.d.ts +0 -4
  34. package/dist/commands/deploy/util/execPromise.d.ts.map +0 -1
  35. package/dist/commands/deploy/util/validate.d.ts +0 -8
  36. package/dist/commands/deploy/util/validate.d.ts.map +0 -1
  37. package/dist/commands/deploy/util/wait.d.ts +0 -9
  38. package/dist/commands/deploy/util/wait.d.ts.map +0 -1
  39. package/dist/commands/esbuild/ESBuildProgram.d.ts +0 -83
  40. package/dist/commands/esbuild/ESBuildProgram.d.ts.map +0 -1
  41. package/dist/commands/esbuild/index.d.ts +0 -3
  42. package/dist/commands/esbuild/index.d.ts.map +0 -1
  43. package/dist/commands/esbuild/util/debounce.d.ts +0 -15
  44. package/dist/commands/esbuild/util/debounce.d.ts.map +0 -1
  45. package/dist/commands/esbuild/util/esbuildPlugins.d.ts +0 -32
  46. package/dist/commands/esbuild/util/esbuildPlugins.d.ts.map +0 -1
  47. package/dist/commands/esbuild/util/getPkgGlobalName.d.ts +0 -6
  48. package/dist/commands/esbuild/util/getPkgGlobalName.d.ts.map +0 -1
  49. package/dist/commands/generate/GenerateProgram.d.ts +0 -18
  50. package/dist/commands/generate/GenerateProgram.d.ts.map +0 -1
  51. package/dist/commands/generate/index.d.ts +0 -3
  52. package/dist/commands/generate/index.d.ts.map +0 -1
  53. package/dist/commands/sync/SyncProgram.d.ts +0 -15
  54. package/dist/commands/sync/SyncProgram.d.ts.map +0 -1
  55. package/dist/commands/sync/index.d.ts +0 -3
  56. package/dist/commands/sync/index.d.ts.map +0 -1
  57. package/dist/commands/sync/when.d.ts +0 -21
  58. package/dist/commands/sync/when.d.ts.map +0 -1
  59. package/dist/index.d.ts +0 -4
  60. package/dist/index.d.ts.map +0 -1
  61. package/dist/index.esm.js +0 -8
  62. package/dist/index.esm.js.map +0 -7
  63. package/dist/index.js +0 -8
  64. package/dist/index.js.map +0 -7
  65. package/dist/utils/AsyncArray.d.ts +0 -21
  66. package/dist/utils/AsyncArray.d.ts.map +0 -1
  67. package/dist/utils/appendScript.d.ts +0 -7
  68. package/dist/utils/appendScript.d.ts.map +0 -1
  69. package/dist/utils/arrayToMap.d.ts +0 -3
  70. package/dist/utils/arrayToMap.d.ts.map +0 -1
  71. package/dist/utils/findParent.d.ts +0 -8
  72. package/dist/utils/findParent.d.ts.map +0 -1
  73. package/dist/utils/index.d.ts +0 -5
  74. package/dist/utils/index.d.ts.map +0 -1
  75. package/dist/utils/nodeCacheDir.d.ts +0 -2
  76. package/dist/utils/nodeCacheDir.d.ts.map +0 -1
  77. package/src/commands/esbuild/__tests__/.temp/package.json +0 -1
  78. package/src/commands/esbuild/__tests__/.temp/src/index.ts +0 -1
  79. package/src/commands/esbuild/util/__tests__/.temp/index.js +0 -1
  80. package/src/commands/esbuild/util/__tests__/esbuildPlugins.test.ts +0 -52
  81. package/src/commands/esbuild/util/esbuildPlugins.ts +0 -196
  82. package/src/commands/generate/__tests__/.temp/README.md +0 -1
  83. package/src/commands/generate/__tests__/.temp/package.json +0 -3
  84. package/src/commands/generate/__tests__/.temp/test-cli/CHANGELOG.md +0 -1
  85. package/src/commands/generate/__tests__/.temp/test-cli/README.md +0 -1
  86. package/src/commands/generate/__tests__/.temp/test-cli/bin.js +0 -3
  87. package/src/commands/generate/__tests__/.temp/test-cli/package.json +0 -33
  88. package/src/commands/generate/__tests__/.temp/test-cli/src/bin.ts +0 -13
  89. package/src/commands/generate/__tests__/.temp/test-cli/src/index.ts +0 -1
  90. package/src/commands/generate/__tests__/.temp/test-cli/tsconfig.json +0 -28
  91. package/src/commands/sync/__tests__/.temp/package.json +0 -16
  92. package/wallaby.conf.js +0 -3
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@liuli-util/cli",
3
- "version": "3.21.0",
3
+ "version": "3.22.0",
4
4
  "description": "一个针对于库和 CLI 应用程序打包的零配置 CLI",
5
- "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
7
- "types": "dist/index.d.ts",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.esm.js",
7
+ "types": "./dist/index.d.ts",
8
8
  "license": "MIT",
9
9
  "bin": {
10
10
  "liuli-cli": "./bin.js"
@@ -20,55 +20,59 @@
20
20
  "registry": "https://registry.npmjs.org/"
21
21
  },
22
22
  "dependencies": {
23
- "@liuli-util/commitlint-standard-config": "^0.1.6",
24
- "@liuli-util/eslint-config-react-ts": "^0.2.1",
25
- "@liuli-util/eslint-config-ts": "^0.4.0",
26
- "@liuli-util/prettier-standard-config": "^0.2.0",
27
- "ajv": "^8.8.2",
23
+ "@liuli-util/commitlint-standard-config": "0.1.6",
24
+ "@liuli-util/eslint-config-react-ts": "0.2.1",
25
+ "@liuli-util/eslint-config-ts": "0.4.0",
26
+ "@liuli-util/prettier-standard-config": "0.3.0",
27
+ "ajv": "^8.11.0",
28
28
  "ajv-formats": "^2.1.1",
29
29
  "ajv-i18n": "^4.2.0",
30
- "chokidar": "^3.5.2",
31
- "commander": "^8.2.0",
32
- "conf": "^10.1.1",
30
+ "chokidar": "^3.5.3",
31
+ "commander": "^9.4.0",
32
+ "conf": "^10.2.0",
33
33
  "enquirer": "^2.3.6",
34
- "esbuild": "^0.13.15",
35
- "fs-extra": "^10.0.0",
36
- "glob": "^7.2.0",
37
- "glob-promise": "^4.2.0",
38
- "json5": "^2.2.0",
39
- "simple-git": "^2.45.1",
34
+ "esbuild": "0.14.39",
35
+ "fs-extra": "^10.1.0",
36
+ "glob": "^8.0.3",
37
+ "glob-promise": "^5.0.0",
38
+ "json5": "^2.2.1",
39
+ "simple-git": "^3.11.0",
40
40
  "spinnies": "^0.5.1",
41
- "ssh2": "^1.5.0",
42
- "ssh2-sftp-client": "^7.2.1",
41
+ "ssh2": "^1.11.0",
42
+ "ssh2-sftp-client": "^9.0.3",
43
43
  "tar": "^6.1.11",
44
- "ts-morph": "^12.0.0"
44
+ "ts-morph": "^15.1.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/fs-extra": "^9.0.13",
48
- "@types/glob": "^7",
49
- "@types/jest": "^27.0.2",
50
- "@types/lodash": "^4.14.178",
51
- "@types/node": "^16.9.6",
52
- "@types/ssh2-sftp-client": "^7.0.0",
53
- "esno": "^0.9.1",
54
- "jest": "^27.4.7",
48
+ "@types/glob": "^7.2.0",
49
+ "@types/jest": "^28.1.6",
50
+ "@types/lodash": "^4.14.182",
51
+ "@types/node": "^18.6.4",
52
+ "@types/ssh2-sftp-client": "^7.1.0",
53
+ "jest": "^28.1.3",
55
54
  "lodash": "^4.17.21",
56
55
  "rimraf": "^3.0.2",
57
- "ts-jest": "^27.1.3",
58
- "type-fest": "^2.3.4",
59
- "typescript": "^4.5.5"
56
+ "ts-jest": "^28.0.7",
57
+ "tsx": "^3.9.0",
58
+ "type-fest": "^2.18.0",
59
+ "typescript": "^4.7.4"
60
60
  },
61
61
  "repository": {
62
62
  "type": "git",
63
63
  "url": "https://github.com/rxliuli/liuli-tools/tree/master/apps/liuli-cli"
64
64
  },
65
+ "exports": {
66
+ "import": "./dist/index.esm.js",
67
+ "require": "./dist/index.js",
68
+ "types": "./dist/index.d.ts"
69
+ },
65
70
  "scripts": {
66
71
  "setup": "pnpm build",
67
- "build": "esno src/bin.ts build cli",
68
- "dev": "esno src/bin.ts build cli -w",
69
- "start": "esno src/bin.ts",
72
+ "build": "tsx src/bin.ts build cli",
73
+ "dev": "tsx src/bin.ts build cli -w",
74
+ "start": "tsx src/bin.ts",
70
75
  "test": "jest --all",
71
76
  "lint": "eslint --fix src/**"
72
- },
73
- "readme": "# @liuli-util/cli\r\n\r\n> [中文](https://github.com/rxliuli/liuli-tools/tree/master/apps/liuli-cli/README.zh-CN.md)\r\n\r\nA zero-configuration CLI for packaging libraries and CLI applications.\r\n\r\n## Getting Started\r\n\r\n### Install\r\n\r\n```sh\r\npnpm i -D @liuli-util/cli # Local installation\r\npnpm i -g @liuli-util/cli # global install\r\n```\r\n\r\n### Packages\r\n\r\n```sh\r\nliuli-cli build lib # Package the library\r\nliuli-cli build cli # Package cli references\r\n```\r\n\r\n> Adding the `-w` option starts the rollup monitoring mode, the dist/ will not be compressed and the dependencies will not be added to the bundle.\r\n\r\n![watchdog mode](https://liuli.dev/images/liuli-cli%20%E7%9B%91%E8%A7%86%E6%A8%A1%E5%BC%8F.gif)\r\n\r\n### Generate\r\n\r\n```sh\r\nliuli-cli generate <name> --template lib # Generate ts-lib project\r\nliuli-cli generate <name> --template cli # generate cli project\r\n```\r\n\r\nutil also supports interactive project creation\r\n\r\n```shell\r\nliuli-cli generate\r\n```\r\n\r\n![liuli-cli interactive creation screenshot](https://liuli.dev/images/liuli-cli%20%E4%BA%A4%E4%BA%92%E5%BC%8F%E5%88%9B%E5%BB%BA%E6%88%AA%E5%9B%BE.gif)\r\n\r\n### Deployment\r\n\r\nSupport for deploying front-end resources to a remote location via sftp/gh-pages, with configuration information in the `deploy` field in package.json\r\n\r\n```sh\r\nliuli deploy\r\n```\r\n\r\npublic\r\n\r\n| configuration | description | defaults |\r\n| ------------- | --------------------------------- | -------- |\r\n| ``type` | deployment type, ``sftp/gh-pgaes` | none |\r\n| `dist` | Static resource directory | None |\r\n| `dest` | deployed remote directory | none |\r\n\r\nsftp\r\n\r\n| configuration | description | defaults |\r\n| -------------------- | ----------------- | -------- |\r\n| `sshConfig.host` | ip address of ssh | |\r\n| `sshConfig.port` | ssh's port number | 22 |\r\n| `sshConfig.username` | ssh's username | |\r\n\r\ngh-pages\r\n\r\n| configuration | description | default |\r\n| ----------------- | ----------------------------------------- | --------------------------------------- |\r\n| `repo?: string` | the git address of the project to push to | the default is the current project |\r\n| `remote?: string` | push remote | defaults to origin |\r\n| `branch?: string` | remote branch name | defaults to gh-pages |\r\n| `add?: boolean` | whether to push incrementally | cleans up the dest directory by default |\r\n\r\nExample configuration for deploying a vuepress documentation site\r\n\r\n```json\r\n{\r\n \"deploy\": {\r\n \"type\": \"gh-pages\",\r\n \"dist\": \"docs/.vuepress/dist\"\r\n }\r\n}\r\n```\r\n\r\n### Sync configuration\r\n\r\n```shell\r\nliuli-cli sync\r\n```\r\n\r\nYou need to specify which configuration to sync in package.json\r\n\r\n```json\r\n{\r\n \"sync\": [\"prettier\", \"workspaces\", \"commitlint\", \"simplehooks\"]\r\n}\r\n```\r\n\r\nCurrently supported configuration items\r\n\r\n- prettier\r\n- commitlint\r\n- simplehooks\r\n- workspaces\r\n- gitignore\r\n- eslint-ts\r\n- eslint-vue-ts\r\n- jest\r\n\r\nFuture goals: By default, this will include checking the cli's own sync (if it needs to be used outside of monorepo), eslint/style-lint, and interactive cli when not configured\r\n\r\n> Note: Currently, only dependencies are synchronized and no installation is performed\r\n\r\nInteractive initialization of synchronized configuration is also supported\r\n\r\n```shell\r\nliuli-cli sync init\r\n```\r\n\r\n## Design philosophy\r\n\r\n- Conventions outweigh configuration and should be left out if possible. VitePress does the same thing, see: https://vitepress.vuejs.org/#lighter-page-weight This leads to a number of constraints, including the following\r\n - The entry file must be `src/index.ts` when packaging the library, and the exit file must be `dist/index.esm.js` and `dist/index.js`\r\n - The entry file must be `src/bin.ts` and the exit file is `dist/bin.js` when packaging the CLI.\r\n - When packaging lib, all dependencies are treated as external dependencies, while when packaging cli, all dependencies are typed into the bundle\r\n\r\n## FAQ\r\n\r\n### Why not bundle external dependencies\r\n\r\nThe main reason is that we want to leave the bundling to the final application, to avoid bundling the same dependencies over and over again, and to avoid dealing with the problem of using `worker_threads` directly on the filesystem in nodejs.\r\n"
77
+ }
74
78
  }
@@ -5,12 +5,12 @@ import { PackageJson } from 'type-fest'
5
5
  import { Project } from 'ts-morph'
6
6
  import { promise } from 'glob-promise'
7
7
  import { IOptions } from 'glob'
8
- import { nativeNodeModules, nodeExternals, userJS } from './util/esbuildPlugins'
9
8
  import { watch } from 'chokidar'
10
9
  import Spinnies from 'spinnies'
11
10
  import { debounce } from './util/debounce'
12
11
  import { parse } from 'json5'
13
12
  import { getPkgGlobalName } from './util/getPkgGlobalName'
13
+ import { nativeNodeModules, nodeExternal, resolve, userJS } from './util'
14
14
 
15
15
  interface ESBuildProgramOptions {
16
16
  base: string
@@ -108,7 +108,7 @@ export class ESBuildProgram {
108
108
  bundle: true,
109
109
  external: [...ESBuildProgram.globalExternal],
110
110
  platform: 'browser',
111
- plugins: [userJS()],
111
+ plugins: [userJS() as any],
112
112
  incremental: this.options.isWatch,
113
113
  absWorkingDir: this.options.base,
114
114
  }
@@ -117,8 +117,6 @@ export class ESBuildProgram {
117
117
  /**
118
118
  * 获取构建 cjs 的选项
119
119
  * @param deps
120
- * @param platform
121
- * @param plugins
122
120
  */
123
121
  getBuildCjsOption({ deps, platform }: { deps: string[]; platform: Platform }): BuildOptions {
124
122
  return {
@@ -132,14 +130,13 @@ export class ESBuildProgram {
132
130
  minify: !this.options.isWatch,
133
131
  incremental: this.options.isWatch,
134
132
  metafile: this.options.isWatch,
133
+ plugins: [resolve([['@liuli-util/esbuild-plugins/src/', '@liuli-util/esbuild-plugins']])] as any,
135
134
  }
136
135
  }
137
136
 
138
137
  /**
139
138
  * 获取构建 esm 的选项
140
139
  * @param deps
141
- * @param platform
142
- * @param plugins
143
140
  */
144
141
  getBuildESMOption({ deps, platform }: { deps: string[]; platform: Platform }): BuildOptions {
145
142
  return {
@@ -153,13 +150,13 @@ export class ESBuildProgram {
153
150
  minify: !this.options.isWatch,
154
151
  incremental: this.options.isWatch,
155
152
  metafile: this.options.isWatch,
153
+ plugins: [resolve([['@liuli-util/esbuild-plugins/src/', '@liuli-util/esbuild-plugins']])] as any,
156
154
  }
157
155
  }
158
156
 
159
157
  /**
160
158
  * 获取构建 iife 的选项
161
159
  * @param deps
162
- * @param platform
163
160
  */
164
161
  getBuildIifeOption({ platform, globalName }: { platform: Platform; globalName: string }): BuildOptions {
165
162
  return {
@@ -180,7 +177,6 @@ export class ESBuildProgram {
180
177
  /**
181
178
  * 获取构建 cli 的选项
182
179
  * @param deps
183
- * @param platform
184
180
  */
185
181
  getBuildCliOption({ platform }: { deps: string[]; platform: Platform }): BuildOptions {
186
182
  const plugins = ESBuildProgram.getPlugins(platform)
@@ -205,7 +201,7 @@ export class ESBuildProgram {
205
201
  static getPlugins(platform: string): Plugin[] {
206
202
  const plugins: Plugin[] = []
207
203
  if (platform === 'node') {
208
- plugins.push(nodeExternals(), nativeNodeModules())
204
+ plugins.push(nodeExternal() as any, nativeNodeModules() as any)
209
205
  }
210
206
  return plugins
211
207
  }
@@ -3,8 +3,8 @@ import * as path from 'path'
3
3
  import { mkdirp, pathExists, remove, writeFile, writeJson } from 'fs-extra'
4
4
  import { PackageJson } from 'type-fest'
5
5
  import { build, Platform } from 'esbuild'
6
- import { nativeNodeModules, nodeExternals } from '../util/esbuildPlugins'
7
6
  import { findParent } from '../../../utils'
7
+ import { nativeNodeModules, nodeExternals } from '@liuli-util/esbuild-plugins/src'
8
8
 
9
9
  describe('测试 ESBuildProgram', () => {
10
10
  const base: string = path.resolve(__dirname, '.temp')
@@ -159,7 +159,7 @@ it('测试 esbuild', async () => {
159
159
  // ...(await ESBuildProgram.getDeps(path.resolve())),
160
160
  ],
161
161
  platform: 'node',
162
- plugins: [nativeNodeModules(), nodeExternals()],
162
+ plugins: [nativeNodeModules(), nodeExternals()] as any,
163
163
  treeShaking: true,
164
164
  })
165
165
  })
@@ -0,0 +1,22 @@
1
+ import { Plugin } from 'esbuild'
2
+
3
+ /**
4
+ * 自动排除所有依赖项
5
+ * golang 不支持 js 的一些语法,参考 https://github.com/evanw/esbuild/issues/1634
6
+ */
7
+ export function autoExternal(): Plugin {
8
+ return {
9
+ name: 'autoExternal',
10
+ setup(build) {
11
+ build.onResolve({ filter: /.*/ }, (args) => {
12
+ if (/^\.{1,2}\//.test(args.path)) {
13
+ return
14
+ }
15
+ return {
16
+ path: args.path,
17
+ external: true,
18
+ }
19
+ })
20
+ },
21
+ }
22
+ }
@@ -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,7 +0,0 @@
1
- export declare class PathUtil {
2
- /**
3
- * 从这个项目的根目录读取,开发环境是 src/../,运行时则是 dist/../
4
- */
5
- static readonly RootPath: string;
6
- }
7
- //# sourceMappingURL=PathUtil.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PathUtil.d.ts","sourceRoot":"","sources":["../src/PathUtil.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAQ;IACnB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAQ,SAAgC;CACzD"}