sugar-scripts 0.2.0-beta.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/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ # sugar-scripts
2
+
3
+ ## 0.2.0-beta.0
4
+
5
+ ### Minor Changes
6
+
7
+ - sugar-scripts 添加统一 running-context,命令都基于此运行
8
+
9
+ ### Patch Changes
10
+
11
+ - 5101c4b: 添加 sugar-scripts,改造为基于 pnpm 的 monorepo
12
+ sugar-server 移除 server,整合为 application
13
+ - Updated dependencies
14
+ - Updated dependencies [5101c4b]
15
+ - sugar-scripts@0.2.0-beta.0
16
+ - sugar-server@0.2.0-beta.0
17
+
18
+ ## 1.0.1
19
+
20
+ ### Patch Changes
21
+
22
+ - 5101c4b: 添加 sugar-scripts,改造为基于 pnpm 的 monorepo
23
+ sugar-server 移除 server,整合为 application
24
+ - Updated dependencies [5101c4b]
25
+ - sugar-scripts@1.0.1
26
+ - sugar-server@0.1.16
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ ## 配置文件
2
+ 1. `sugar.project.ts`
3
+ 2. `sugar.package.ts`
4
+ 3. `sugar.build.ts`
5
+
6
+
7
+ #### sugar.project.ts 配置文件
8
+ ```ts
9
+ import type {
10
+ types
11
+ } from 'sugar-scripts';
12
+
13
+ // 待定
14
+ ```
15
+
16
+
17
+ #### sugar.package.js 配置文件
18
+ ```ts
19
+ import type {
20
+ types
21
+ } from 'sugar-scripts';
22
+
23
+ export const packageConfig: types.PackageConfig;
24
+ ```
25
+
26
+
27
+
28
+
29
+ #### sugar.build.js 配置文件
30
+ ```ts
31
+ import type {
32
+ types
33
+ } from 'sugar-scripts';
34
+
35
+ export const browserWebpackConfig: types.CustomWebpackConfig;
36
+
37
+ export const serverWebpackConfig: types.CustomWebpackConfig;
38
+ ```
39
+
40
+
41
+ ## sugar-scripts cli
42
+
43
+ ### start
44
+ ```bash
45
+ sugar-scripts start xxx.ts --port 9000
46
+ ```
47
+
48
+ ### info
49
+ ```bash
50
+ sugar-scripts info
51
+ ```
52
+
53
+ ### build
54
+ ```bash
55
+ sugar-scripts build
56
+ ```
57
+
58
+
59
+ ### cache
60
+ ```bash
61
+ sugar-scripts cache
62
+ ```
63
+
64
+
package/bin/cli-ts.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ts-node
2
+
3
+ require('../src/commander');
package/bin/cli.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('../lib/commander');
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "sugar-scripts",
3
+ "version": "0.2.0-beta.0",
4
+ "description": "",
5
+ "main": "lib/index.js",
6
+ "bin": {
7
+ "sugar-scripts": "./bin/cli.js"
8
+ },
9
+ "author": "",
10
+ "license": "MIT",
11
+ "dependencies": {
12
+ "babel-loader": "^8.0.6",
13
+ "chalk": "~4.1.2",
14
+ "commander": "^8.1.0",
15
+ "glob": "~7.2.0",
16
+ "koa-send": "~5.0.1",
17
+ "sugar-scripts": "^0.2.0-beta.0",
18
+ "sugar-server": "^0.2.0-beta.0",
19
+ "ts-loader": "^9.3.0",
20
+ "ts-node": "^10.4.0",
21
+ "webpack": "^5",
22
+ "webpack-chain": "~6.5.1",
23
+ "webpack-manifest-plugin": "^3.2.0"
24
+ },
25
+ "devDependencies": {
26
+ "@babel/core": "^7.7.0",
27
+ "@babel/node": "^7.7.0",
28
+ "@babel/plugin-proposal-class-properties": "^7.7.0",
29
+ "@babel/plugin-proposal-decorators": "^7.7.0",
30
+ "@babel/plugin-proposal-object-rest-spread": "^7.7.4",
31
+ "@babel/plugin-transform-arrow-functions": "^7.7.4",
32
+ "@babel/plugin-transform-runtime": "^7.8.3",
33
+ "@babel/preset-env": "^7.7.0",
34
+ "@babel/preset-react": "^7.7.0",
35
+ "@babel/preset-typescript": "^7.7.4",
36
+ "@babel/runtime": "^7.8.3",
37
+ "@babel/runtime-corejs3": "^7.8.3",
38
+ "@types/glob": "~7.2.0",
39
+ "@types/koa-send": "~4.1.3",
40
+ "@types/node": "^18.0.0",
41
+ "@types/webpack": "^5",
42
+ "babel-loader": "^8.0.6",
43
+ "babel-plugin-parameter-decorator": "^1.0.16",
44
+ "typescript": "^4.3.5"
45
+ },
46
+ "peerDependencies": {
47
+ "ts-loader": "^9.3.0"
48
+ },
49
+ "scripts": {
50
+ "clean": "rm -fr lib",
51
+ "build": "npm run clean && tsc"
52
+ }
53
+ }
@@ -0,0 +1 @@
1
+ export * from './static';
@@ -0,0 +1,42 @@
1
+ import send from 'koa-send';
2
+
3
+ import {
4
+ router,
5
+ parameter,
6
+ Controller
7
+ } from 'sugar-server';
8
+
9
+ const { GetRoute } = router;
10
+
11
+ export function createStaticController ({
12
+ staticResourcesPath,
13
+ prefix = '/'
14
+ }: {
15
+ staticResourcesPath: string,
16
+ prefix?: string;
17
+ }): typeof Controller {
18
+ class StaticController extends Controller {
19
+ static prefix = prefix;
20
+
21
+ @GetRoute('*')
22
+ @parameter.getter
23
+ async status (
24
+ @parameter.Context ctx: any
25
+ ) {
26
+ const routerPath = ctx.routerPath || ctx.path;
27
+ const filePath = routerPath.substr(prefix.length);
28
+
29
+ if (filePath) {
30
+ await send(
31
+ ctx,
32
+ filePath,
33
+ {
34
+ root: staticResourcesPath,
35
+ maxAge: 86400000
36
+ });
37
+ }
38
+ }
39
+ }
40
+
41
+ return StaticController;
42
+ }
@@ -0,0 +1,95 @@
1
+ import path from 'path';
2
+ import chalk from 'chalk';
3
+ import { Command } from 'commander';
4
+
5
+ import {
6
+ initRunningContext
7
+ } from '../core/init-running-context';
8
+ import {
9
+ build
10
+ } from '../core/build';
11
+ import {
12
+ info
13
+ } from '../core/info';
14
+ import {
15
+ clean as cacheClean
16
+ } from '../core/cache';
17
+ import {
18
+ runApplication
19
+ } from '../core/run-application';
20
+
21
+ const program = new Command();
22
+ program
23
+ .version('1.0.0');
24
+
25
+ program
26
+ .command('info')
27
+ .description('工程信息')
28
+ .option('--dir <dir>', '自定义运行的目录')
29
+ .action(async (options, command) => {
30
+ const cwd = process.cwd();
31
+ const dir = options.dir ? path.resolve(cwd, options.dir) : cwd
32
+ // process.exit();
33
+ })
34
+
35
+ program
36
+ .command('build')
37
+ .description('构建服务')
38
+ .option('--dir <dir>', '自定义运行的目录')
39
+ .action(async (options, command) => {
40
+ const cwd = process.cwd();
41
+ const dir = options.dir ? path.resolve(cwd, options.dir) : cwd
42
+
43
+ const context = await initRunningContext(dir);
44
+ await build(
45
+ context
46
+ );
47
+ console.log(`✅ ${chalk.bold.green('构建成功')}`);
48
+ })
49
+
50
+
51
+ const cacheCommand = new Command();
52
+ cacheCommand
53
+ .name('cache')
54
+ .description('构建缓存管理');
55
+
56
+ cacheCommand
57
+ .command('clean')
58
+ .description('清理构建缓存')
59
+ .option('--dir <dir>', '自定义运行的目录')
60
+ .action(async (options, command) => {
61
+ const cwd = process.cwd();
62
+ const dir = options.dir ? path.resolve(cwd, options.dir) : cwd;
63
+ const context = await initRunningContext(dir);
64
+ await cacheClean(context);
65
+ console.log(`✅ ${chalk.bold.green('清理构建缓存成功')}`);
66
+ })
67
+
68
+ program.addCommand(cacheCommand)
69
+
70
+ program
71
+ .command('start')
72
+ .description('启动开发服务')
73
+ .option('--dir <dir>', '自定义运行的目录')
74
+ .option('--port <port>', '指定运行的端口')
75
+ .action(async (options, command) => {
76
+ const cwd = process.cwd();
77
+ const dir = options.dir ? path.resolve(cwd, options.dir) : cwd
78
+ const port = +options.port;
79
+
80
+ const context = await initRunningContext(dir);
81
+ const appFilePath = context.getStartFilePath()
82
+
83
+ if (!appFilePath) return;
84
+ const App = require(
85
+ appFilePath
86
+ ).default;
87
+
88
+ runApplication(
89
+ App,
90
+ port
91
+ );
92
+ console.log(`✅ ${chalk.bold.green(`启动服务成功,端口:${port}`)}`);
93
+ })
94
+
95
+ program.parse(process.argv);
@@ -0,0 +1,42 @@
1
+ const path = require('path');
2
+
3
+ export const babelConfig = {
4
+ presets: [
5
+ [
6
+ '@babel/preset-typescript',
7
+ {
8
+ 'onlyRemoveTypeImports': true
9
+ }
10
+ ],
11
+ ['@babel/preset-react'],
12
+ [
13
+ '@babel/preset-env',
14
+ {
15
+ loose: true,
16
+ targets: {
17
+ node: 'current'
18
+ }
19
+ }
20
+ ]
21
+ ],
22
+ plugins: [
23
+ // [
24
+ // '@babel/plugin-transform-runtime',
25
+ // {
26
+ // corejs: 3,
27
+ // regenerator: true
28
+ // }
29
+ // ],
30
+ '@babel/plugin-transform-arrow-functions',
31
+ '@babel/plugin-proposal-object-rest-spread',
32
+ [
33
+ '@babel/plugin-proposal-decorators',
34
+ { legacy: true }
35
+ ],
36
+ [
37
+ '@babel/plugin-proposal-class-properties',
38
+ { loose: true }
39
+ ],
40
+ ['babel-plugin-parameter-decorator']
41
+ ]
42
+ }
@@ -0,0 +1,43 @@
1
+ export const babelConfig = {
2
+ presets: [
3
+ ['@babel/preset-typescript'],
4
+ ['@babel/preset-react'],
5
+ [
6
+ '@babel/preset-env',
7
+ {
8
+ loose: true,
9
+ targets: {
10
+ chrome: '58',
11
+ ie: '11'
12
+ }
13
+ // useBuiltIns: "entry"
14
+ // corejs: false
15
+ }
16
+ ]
17
+ ],
18
+ plugins: [
19
+ [
20
+ '@babel/plugin-transform-runtime',
21
+ {
22
+ // "corejs": 3,
23
+ // polyfill: false,
24
+ corejs: false,
25
+ regenerator: true
26
+ }
27
+ ],
28
+ '@babel/plugin-transform-arrow-functions',
29
+ '@babel/plugin-proposal-object-rest-spread',
30
+ [
31
+ '@babel/plugin-proposal-decorators',
32
+ {
33
+ legacy: true
34
+ }
35
+ ],
36
+ [
37
+ '@babel/plugin-proposal-class-properties',
38
+ {
39
+ loose: true
40
+ }
41
+ ]
42
+ ]
43
+ }
@@ -0,0 +1,5 @@
1
+ export const SUGAR_PACKAGE_CONFIG_FILENAME = 'sugar.package';
2
+ export const SUGAR_PROJECT_CONFIG_FILENAME = 'sugar.project';
3
+
4
+ export const SUGAR_BUILD_EXPORT_BROWSER = 'browserWebpackConfig';
5
+ export const SUGAR_BUILD_EXPORT_SERVER = 'serverWebpackConfig';
@@ -0,0 +1,98 @@
1
+ import path from 'path';
2
+ import * as tsNode from 'ts-node';
3
+
4
+ import {
5
+ SugarScriptsContext
6
+ } from './running-context';
7
+
8
+ import {
9
+ mergeBrowserEntryFromServer,
10
+ mergeBuildDllConfig,
11
+ mergeBrowserCustomConfig
12
+ } from '../webpack/webpack.browser';
13
+ import {
14
+ mergeServerEntry,
15
+ mergeServerCustomConfig
16
+ } from '../webpack/webpack.server';
17
+ import {
18
+ createCommonChainConfig,
19
+ mergeDllReferences
20
+ } from '../webpack/webpack.common';
21
+ import {
22
+ runWebpack
23
+ } from '../webpack/run-webpack';
24
+
25
+
26
+ export const build = async (
27
+ context: SugarScriptsContext
28
+ ) => {
29
+ tsNode.register({
30
+ cwd: context.root,
31
+ projectSearchDir: context.root,
32
+ project: path.resolve(context.root, './tsconfig.json'),
33
+ transpileOnly: true
34
+ })
35
+
36
+ await buildBrowser(
37
+ context
38
+ )
39
+
40
+ await buildServer(
41
+ context
42
+ )
43
+ }
44
+
45
+ const buildBrowser = async (context: SugarScriptsContext) => {
46
+ if (!context.packageConfig.browser) return;
47
+ const browserConfig = context.packageConfig.browser;
48
+
49
+ const chainConfig = await createCommonChainConfig(
50
+ context,
51
+ browserConfig.output
52
+ );
53
+
54
+ await mergeBrowserEntryFromServer(
55
+ context,
56
+ chainConfig
57
+ )
58
+
59
+ // 合并其他已经构建好的dll
60
+ await mergeDllReferences(
61
+ context,
62
+ chainConfig,
63
+ )
64
+
65
+ // 如果是dll
66
+ await mergeBuildDllConfig(
67
+ context,
68
+ chainConfig
69
+ )
70
+
71
+ await mergeBrowserCustomConfig(
72
+ context,
73
+ chainConfig
74
+ )
75
+
76
+ await runWebpack(chainConfig);
77
+ }
78
+
79
+
80
+ const buildServer = async (context: SugarScriptsContext) => {
81
+ if (!context.packageConfig.server) return;
82
+ const serverConfig = context.packageConfig.server;
83
+
84
+ const chainConfig = await createCommonChainConfig(
85
+ context,
86
+ serverConfig.output
87
+ );
88
+
89
+ await mergeServerEntry(
90
+ context,
91
+ chainConfig
92
+ );
93
+ await mergeServerCustomConfig(
94
+ context,
95
+ chainConfig
96
+ );
97
+ await runWebpack(chainConfig);
98
+ }
@@ -0,0 +1,15 @@
1
+ import path from 'path';
2
+ import {
3
+ SugarScriptsContext
4
+ } from './running-context';
5
+ import {
6
+ rm
7
+ } from '../shared/file-helpers';
8
+
9
+ export const clean = (
10
+ context: SugarScriptsContext
11
+ ) => {
12
+ return rm(
13
+ context.getCacheDir()
14
+ );
15
+ }
@@ -0,0 +1,189 @@
1
+ import path from 'path';
2
+ import {
3
+ Application,
4
+ Controller,
5
+ ControllerContext
6
+ } from 'sugar-server';
7
+
8
+ import {
9
+ CustomRender
10
+ } from '../custom-config.type';
11
+
12
+ export const ENTRIES_KEY = Symbol('_sugar_entries');
13
+ export const ENTRIES_CONFIG_KEY = Symbol('_sugar_entries_config');
14
+
15
+ export interface EntryConfig {
16
+ filePath: string
17
+ }
18
+
19
+ export interface EntriesController extends Controller {
20
+ [ENTRIES_KEY]: EntryConfig[]
21
+ }
22
+
23
+ const defaultRender: CustomRender = (
24
+ ctx,
25
+ entries,
26
+ custom
27
+ ) => {
28
+ return entries.toString();
29
+ }
30
+
31
+ const render: CustomRender = (
32
+ ...args
33
+ ) => {
34
+ let currentRender = defaultRender;
35
+ console.log('SUGAR_PROJECT_RENDER', process.env.SUGAR_PROJECT_RENDER)
36
+ if (process.env.SUGAR_PROJECT_RENDER) {
37
+ try {
38
+ currentRender = require(process.env.SUGAR_PROJECT_RENDER).default;
39
+ console.log('load custom render success');
40
+ } catch (e) {}
41
+ }
42
+ return currentRender(
43
+ ...args
44
+ )
45
+ }
46
+
47
+ // discuss:需要string[] 吗?
48
+ export type RegisterFilePath = string | {[key: string]: string}
49
+
50
+ export function register (
51
+ filePath: RegisterFilePath
52
+ ) {
53
+ return function (
54
+ target: Controller,
55
+ key: string,
56
+ descriptor: PropertyDescriptor
57
+ ) {
58
+ if (!Object.getOwnPropertyDescriptor(target, ENTRIES_KEY)) {
59
+ Object.defineProperty(target, ENTRIES_KEY, {
60
+ configurable: true,
61
+ enumerable: false,
62
+ writable: true,
63
+ value: []
64
+ })
65
+ }
66
+
67
+ if (typeof filePath === 'string') {
68
+ (target as EntriesController)[ENTRIES_KEY].push({
69
+ filePath
70
+ })
71
+ } else {
72
+ Object.keys(filePath).forEach((filePathKey) => {
73
+ const oneFilePath = filePath[filePathKey];
74
+ (target as EntriesController)[ENTRIES_KEY].push({
75
+ filePath: oneFilePath
76
+ })
77
+ })
78
+ }
79
+
80
+ const oldValue = descriptor.value;
81
+ descriptor.value = async function (
82
+ ctx: ControllerContext,
83
+ ...args: any
84
+ ) {
85
+ // ctx.app
86
+ let oldResult;
87
+ if (oldValue) {
88
+ oldResult = await oldValue.call(this, ...args);
89
+ }
90
+
91
+ let envEntries = ENV_ENTRIES;
92
+ if (
93
+ (ctx.app.constructor as any).ENTRIES
94
+ ) {
95
+ envEntries = (ctx.app.constructor as any).ENTRIES;
96
+ }
97
+ console.log('envEntries', envEntries, ENV_ENTRIES )
98
+
99
+ let entries: string[] | {[key: string]: string[]} = [];
100
+ if (typeof filePath === 'string') {
101
+ entries = envEntries[filePath] || [];
102
+ } else {
103
+ entries = Object.keys(filePath).reduce((
104
+ currentEntries,
105
+ filePathKey
106
+ ) => {
107
+ const oneFilePath = filePath[filePathKey];
108
+ currentEntries[filePathKey] = envEntries[oneFilePath];
109
+ return currentEntries;
110
+ }, {} as {[key: string]: string[]})
111
+ }
112
+
113
+ console.log(
114
+ 'will search file',
115
+ envEntries,
116
+ filePath,
117
+ entries
118
+ )
119
+
120
+ return render(
121
+ ctx,
122
+ entries,
123
+ oldResult
124
+ );
125
+ }
126
+ }
127
+ }
128
+
129
+ export const ENTRY_WEBPACK_INJECT_KEY = 'ENTRY_WEBPACK_INJECT_KEY';
130
+
131
+ export const ENV_ENTRIES = (process.env.SUGAR_PROJECT_ENTRIES || {}) as {
132
+ [entryKey: string]: string[]
133
+ };
134
+
135
+ export function getEntryUrl (
136
+ filePath: string
137
+ ) {
138
+ return '';
139
+ }
140
+
141
+ export function getEntries (
142
+ dirname: string
143
+ ) {
144
+ let entries = {};
145
+
146
+ require(
147
+ path.resolve(
148
+ dirname,
149
+ ''
150
+ )
151
+ )
152
+ }
153
+
154
+ export function getEntriesFromController (
155
+ controller: Controller
156
+ ) {
157
+ return (controller as EntriesController)[ENTRIES_KEY] || [];
158
+ }
159
+
160
+ export function getEntriesFromControllers (
161
+ controllers: Controller[],
162
+ root: string
163
+ ) {
164
+ const entries: {
165
+ [key: string]: string
166
+ } = {};
167
+ controllers.forEach(
168
+ (controller) => {
169
+ getEntriesFromController(controller).forEach(({ filePath }) => {
170
+ entries[filePath] = path.resolve(
171
+ root,
172
+ filePath
173
+ )
174
+ })
175
+ }
176
+ )
177
+ return entries;
178
+ }
179
+
180
+ export function getEntriesFromApplicationClass (
181
+ ApplicationClass: typeof Application,
182
+ root: string
183
+ ) {
184
+ const app = new ApplicationClass();
185
+ return getEntriesFromControllers(
186
+ app.controllers,
187
+ root
188
+ )
189
+ }
@@ -0,0 +1,5 @@
1
+ import {
2
+ router
3
+ } from 'sugar-server';
4
+
5
+ export const info = () => {}