@deot/dev-dever 2.4.0 → 2.5.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.
- package/dist/index.cjs +19 -10
- package/dist/index.es.js +20 -11
- package/package.json +5 -2
- package/shared.config.ts +111 -40
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,8 @@ const devShared = require('@deot/dev-shared');
|
|
|
8
8
|
const fs$1 = require('fs-extra');
|
|
9
9
|
const vite = require('vite');
|
|
10
10
|
const chalk = require('chalk');
|
|
11
|
+
const sharedVueConfig = require('@deot/dev-vue');
|
|
12
|
+
const sharedReactConfig = require('@deot/dev-react');
|
|
11
13
|
const fs = require('node:fs');
|
|
12
14
|
const ejs = require('ejs');
|
|
13
15
|
|
|
@@ -46,7 +48,7 @@ const walk = (dir) => {
|
|
|
46
48
|
const paths = fullpath.split("/") || [];
|
|
47
49
|
const stat = fs__namespace.statSync(fullpath);
|
|
48
50
|
const extname = path__namespace.extname(fullpath);
|
|
49
|
-
if (stat.isFile() && /\.(t|j)sx
|
|
51
|
+
if (stat.isFile() && /\.((t|j)sx?|vue)$/.test(extname) && paths.length >= 2 && paths[paths.length - 2] === "examples") {
|
|
50
52
|
const basename = path__namespace.basename(file, extname);
|
|
51
53
|
let name = path__namespace.join(dir, basename).split("/");
|
|
52
54
|
name.splice(name.length - 2, 1);
|
|
@@ -78,9 +80,8 @@ const run = (options) => devShared.Utils.autoCatch(async () => {
|
|
|
78
80
|
}
|
|
79
81
|
if (options.dryRun)
|
|
80
82
|
return devShared.Shell.spawn(`echo development`);
|
|
81
|
-
const { cwd, workspace, packageOptionsMap, packageDirsMap } = locals;
|
|
82
|
-
const
|
|
83
|
-
const packageFolderName = devShared.Locals.getPackageFolderName(packageName);
|
|
83
|
+
const { cwd, workspace, packageOptionsMap, packageDirsMap, subpackagesMap } = locals;
|
|
84
|
+
const packageFolderName = devShared.Locals.getPackageFolderName(options.packageName);
|
|
84
85
|
const packageOptions = packageOptionsMap[packageFolderName];
|
|
85
86
|
const packageDir = packageDirsMap[packageFolderName];
|
|
86
87
|
options.watch = true;
|
|
@@ -94,12 +95,6 @@ const run = (options) => devShared.Utils.autoCatch(async () => {
|
|
|
94
95
|
delete options.workspace;
|
|
95
96
|
delete options.packageName;
|
|
96
97
|
let { entries, html } = get();
|
|
97
|
-
process.env.DEV_OPTIONS = encodeURIComponent(JSON.stringify({
|
|
98
|
-
...options,
|
|
99
|
-
workspace,
|
|
100
|
-
entries,
|
|
101
|
-
html
|
|
102
|
-
}));
|
|
103
98
|
if (!entries.length)
|
|
104
99
|
return devShared.Shell.spawn(`echo no entry file found!`);
|
|
105
100
|
let options$ = {
|
|
@@ -113,7 +108,21 @@ const run = (options) => devShared.Utils.autoCatch(async () => {
|
|
|
113
108
|
options$.configFile = path__namespace.relative(cwd, path__namespace.resolve(cwd, "./dev.config.ts"));
|
|
114
109
|
} else {
|
|
115
110
|
options$.configFile = path__namespace.relative(cwd, path__namespace.resolve(dirname, "../shared.config.ts"));
|
|
111
|
+
const { vuePackage, reactPackage } = options;
|
|
112
|
+
if (vuePackage) {
|
|
113
|
+
options$ = vite.mergeConfig(sharedVueConfig, options$);
|
|
114
|
+
}
|
|
115
|
+
if (reactPackage) {
|
|
116
|
+
options$ = vite.mergeConfig(sharedReactConfig, options$);
|
|
117
|
+
}
|
|
116
118
|
}
|
|
119
|
+
process.env.DEV_OPTIONS = encodeURIComponent(JSON.stringify({
|
|
120
|
+
...options,
|
|
121
|
+
workspace,
|
|
122
|
+
entries,
|
|
123
|
+
html,
|
|
124
|
+
subpackagesMap
|
|
125
|
+
}));
|
|
117
126
|
const server = await vite.createServer(options$);
|
|
118
127
|
const $server = await server.listen();
|
|
119
128
|
const { local = [], network = [] } = $server.resolvedUrls || {};
|
package/dist/index.es.js
CHANGED
|
@@ -2,8 +2,10 @@ import * as path from 'node:path';
|
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { Locals, Utils, Shell, Logger } from '@deot/dev-shared';
|
|
4
4
|
import fs$1 from 'fs-extra';
|
|
5
|
-
import { createServer } from 'vite';
|
|
5
|
+
import { mergeConfig, createServer } from 'vite';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
+
import sharedVueConfig from '@deot/dev-vue';
|
|
8
|
+
import sharedReactConfig from '@deot/dev-react';
|
|
7
9
|
import * as fs from 'node:fs';
|
|
8
10
|
import { render } from 'ejs';
|
|
9
11
|
|
|
@@ -22,7 +24,7 @@ const walk = (dir) => {
|
|
|
22
24
|
const paths = fullpath.split("/") || [];
|
|
23
25
|
const stat = fs.statSync(fullpath);
|
|
24
26
|
const extname = path.extname(fullpath);
|
|
25
|
-
if (stat.isFile() && /\.(t|j)sx
|
|
27
|
+
if (stat.isFile() && /\.((t|j)sx?|vue)$/.test(extname) && paths.length >= 2 && paths[paths.length - 2] === "examples") {
|
|
26
28
|
const basename = path.basename(file, extname);
|
|
27
29
|
let name = path.join(dir, basename).split("/");
|
|
28
30
|
name.splice(name.length - 2, 1);
|
|
@@ -54,9 +56,8 @@ const run = (options) => Utils.autoCatch(async () => {
|
|
|
54
56
|
}
|
|
55
57
|
if (options.dryRun)
|
|
56
58
|
return Shell.spawn(`echo development`);
|
|
57
|
-
const { cwd, workspace, packageOptionsMap, packageDirsMap } = locals;
|
|
58
|
-
const
|
|
59
|
-
const packageFolderName = Locals.getPackageFolderName(packageName);
|
|
59
|
+
const { cwd, workspace, packageOptionsMap, packageDirsMap, subpackagesMap } = locals;
|
|
60
|
+
const packageFolderName = Locals.getPackageFolderName(options.packageName);
|
|
60
61
|
const packageOptions = packageOptionsMap[packageFolderName];
|
|
61
62
|
const packageDir = packageDirsMap[packageFolderName];
|
|
62
63
|
options.watch = true;
|
|
@@ -70,12 +71,6 @@ const run = (options) => Utils.autoCatch(async () => {
|
|
|
70
71
|
delete options.workspace;
|
|
71
72
|
delete options.packageName;
|
|
72
73
|
let { entries, html } = get();
|
|
73
|
-
process.env.DEV_OPTIONS = encodeURIComponent(JSON.stringify({
|
|
74
|
-
...options,
|
|
75
|
-
workspace,
|
|
76
|
-
entries,
|
|
77
|
-
html
|
|
78
|
-
}));
|
|
79
74
|
if (!entries.length)
|
|
80
75
|
return Shell.spawn(`echo no entry file found!`);
|
|
81
76
|
let options$ = {
|
|
@@ -89,7 +84,21 @@ const run = (options) => Utils.autoCatch(async () => {
|
|
|
89
84
|
options$.configFile = path.relative(cwd, path.resolve(cwd, "./dev.config.ts"));
|
|
90
85
|
} else {
|
|
91
86
|
options$.configFile = path.relative(cwd, path.resolve(dirname, "../shared.config.ts"));
|
|
87
|
+
const { vuePackage, reactPackage } = options;
|
|
88
|
+
if (vuePackage) {
|
|
89
|
+
options$ = mergeConfig(sharedVueConfig, options$);
|
|
90
|
+
}
|
|
91
|
+
if (reactPackage) {
|
|
92
|
+
options$ = mergeConfig(sharedReactConfig, options$);
|
|
93
|
+
}
|
|
92
94
|
}
|
|
95
|
+
process.env.DEV_OPTIONS = encodeURIComponent(JSON.stringify({
|
|
96
|
+
...options,
|
|
97
|
+
workspace,
|
|
98
|
+
entries,
|
|
99
|
+
html,
|
|
100
|
+
subpackagesMap
|
|
101
|
+
}));
|
|
93
102
|
const server = await createServer(options$);
|
|
94
103
|
const $server = await server.listen();
|
|
95
104
|
const { local = [], network = [] } = $server.resolvedUrls || {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deot/dev-dever",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.es.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,11 +21,14 @@
|
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@deot/dev-
|
|
24
|
+
"@deot/dev-react": "^2.5.0",
|
|
25
|
+
"@deot/dev-shared": "^2.5.0",
|
|
26
|
+
"@deot/dev-vue": "^2.5.0",
|
|
25
27
|
"ejs": "^3.1.9",
|
|
26
28
|
"vite": "^4.4.9"
|
|
27
29
|
},
|
|
28
30
|
"devDependencies": {
|
|
31
|
+
"@deot/dev-test": "^2.5.0",
|
|
29
32
|
"cross-env": "^7.0.3"
|
|
30
33
|
}
|
|
31
34
|
}
|
package/shared.config.ts
CHANGED
|
@@ -4,46 +4,21 @@ import { createRequire } from "node:module";
|
|
|
4
4
|
import { defineConfig } from 'vitest/config';
|
|
5
5
|
import type { UserConfig, ViteDevServer } from 'vite';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* https://github.com/vuejs/core/issues/8303
|
|
9
|
+
* to fix error: ReferenceError: __name is not defined
|
|
10
|
+
*/
|
|
11
|
+
let __defProp = Object.defineProperty;
|
|
12
|
+
let __name = (target: any, value: any) => __defProp(target, 'name', { value, configurable: true });
|
|
13
|
+
globalThis.__name = globalThis.__name || __name;
|
|
14
|
+
|
|
7
15
|
const cwd = process.cwd();
|
|
8
16
|
|
|
9
17
|
// devOptions
|
|
10
18
|
const devOptions = JSON.parse(decodeURIComponent(process.env.DEV_OPTIONS || '{}'));
|
|
11
|
-
const { workspace, html } = devOptions;
|
|
12
|
-
|
|
13
|
-
// alias
|
|
14
|
-
const replacement = (name: string) => path.resolve(cwd, `./packages/${name}/src`);
|
|
15
|
-
const { name } = createRequire(cwd)(path.resolve(cwd, workspace ? `${workspace}/index` : '', 'package.json'));
|
|
16
|
-
|
|
17
|
-
const getHtmlContent = async (url: string) => {
|
|
18
|
-
let fullpath = path.join(cwd, workspace, url);
|
|
19
|
-
|
|
20
|
-
if (
|
|
21
|
-
/^\/?@vite/.test(url)
|
|
22
|
-
|| (fs.existsSync(fullpath) && fs.statSync(fullpath).isFile())
|
|
23
|
-
) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (url === '/') return html;
|
|
28
|
-
|
|
29
|
-
const info = url.split('/').filter(i => !!i);
|
|
30
|
-
|
|
31
|
-
const prefix = info.slice(0, -1);
|
|
32
|
-
const entry = info.slice(-1)[0];
|
|
33
|
-
|
|
34
|
-
if (prefix[prefix.length - 1] !== 'examples') {
|
|
35
|
-
prefix.push('examples');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
fullpath = path.join(
|
|
39
|
-
cwd,
|
|
40
|
-
workspace,
|
|
41
|
-
prefix.join('/'),
|
|
42
|
-
`${entry?.replace(/(\.html)$/, '.ts')}`
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
if (!fs.existsSync(fullpath)) return /\.[\s\S]+$/.test(entry) ? undefined : html;
|
|
19
|
+
const { workspace, html, subpackagesMap } = devOptions;
|
|
46
20
|
|
|
21
|
+
const generateIndexHtml = (url: string, inject: string) => {
|
|
47
22
|
let contents = '';
|
|
48
23
|
contents += `<!DOCTYPE html>\n`;
|
|
49
24
|
contents += `<html lang="en">\n`;
|
|
@@ -53,14 +28,81 @@ const getHtmlContent = async (url: string) => {
|
|
|
53
28
|
contents += ` <title>demo-${url}</title>\n`;
|
|
54
29
|
contents += ` </head>\n`;
|
|
55
30
|
contents += ` <body>\n`;
|
|
31
|
+
contents += ` <div id="app"></div>\n`;
|
|
56
32
|
contents += ` <script type="module">\n`;
|
|
57
|
-
contents +=
|
|
33
|
+
contents += inject;
|
|
34
|
+
|
|
58
35
|
contents += ` </script>\n`;
|
|
59
36
|
contents += ` </body>\n`;
|
|
60
37
|
contents += `</html>\n`;
|
|
38
|
+
|
|
61
39
|
return contents;
|
|
62
40
|
};
|
|
63
41
|
|
|
42
|
+
const getVirtualHtml = async (url: string) => {
|
|
43
|
+
const info = url.split('/').filter(i => !!i);
|
|
44
|
+
|
|
45
|
+
const prefix = info.slice(0, -1);
|
|
46
|
+
const entry = info.slice(-1)[0];
|
|
47
|
+
|
|
48
|
+
if (prefix[prefix.length - 1] !== 'examples') {
|
|
49
|
+
prefix.push('examples');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (workspace && prefix[0] !== workspace) {
|
|
53
|
+
prefix.unshift(workspace);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const dir = path.join(cwd, prefix.join('/'));
|
|
57
|
+
const isExist = (ext: string) => {
|
|
58
|
+
const fullpath = path.join(dir, `${entry.replace(/(.*)(\..*)$/, '$1') + ext}`);
|
|
59
|
+
return fs.existsSync(fullpath) ? fullpath : false;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const htmlFullpath = isExist('.html');
|
|
63
|
+
if (htmlFullpath) {
|
|
64
|
+
return fs.readFileSync(htmlFullpath).toString();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const tsFullpath = isExist('.ts');
|
|
68
|
+
if (tsFullpath) {
|
|
69
|
+
let inject = '';
|
|
70
|
+
inject += ` import "/${path.relative(cwd, tsFullpath)}";\n`;
|
|
71
|
+
return generateIndexHtml(url, inject);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const vueFullpath = isExist('.vue');
|
|
75
|
+
if (vueFullpath) {
|
|
76
|
+
let inject = '';
|
|
77
|
+
inject += ` import { createApp } from "vue"\n`;
|
|
78
|
+
inject += ` import App from "/${path.relative(cwd, vueFullpath)}";\n`;
|
|
79
|
+
inject += ` const app = createApp(App);\n`;
|
|
80
|
+
inject += ` app.mount("#app");\n`;
|
|
81
|
+
inject += ` typeof window !== "undefined" && (window.app = app);\n`;
|
|
82
|
+
return generateIndexHtml(url, inject);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const tsxFullpath = isExist('.tsx');
|
|
86
|
+
if (tsxFullpath) {
|
|
87
|
+
let inject = '';
|
|
88
|
+
inject += ` import React, { StrictMode } from 'react';`;
|
|
89
|
+
inject += ` import { createRoot } from 'react-dom/client';`;
|
|
90
|
+
inject += ` import App from "/${path.relative(cwd, tsxFullpath)}";\n`;
|
|
91
|
+
inject += ` const h = React.createElement\n`;
|
|
92
|
+
inject += ` const app = createRoot(document.getElementById('app'));\n`;
|
|
93
|
+
inject += ` app.render(h(StrictMode, {}, h(App)))\n`;
|
|
94
|
+
|
|
95
|
+
return generateIndexHtml(url, inject);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
// alias
|
|
101
|
+
const require$ = createRequire(cwd);
|
|
102
|
+
const getPackageName = (name: string) => (require$(path.resolve(cwd, workspace ? `${workspace}/${name}` : '', 'package.json'))).name;
|
|
103
|
+
const replacement = (name: string, isSubpackage?: boolean) => path.resolve(cwd, `./packages/${name}`, isSubpackage ? 'index.ts' : './src');
|
|
104
|
+
const name = getPackageName('index');
|
|
105
|
+
|
|
64
106
|
export default defineConfig({
|
|
65
107
|
resolve: workspace
|
|
66
108
|
? {
|
|
@@ -69,6 +111,15 @@ export default defineConfig({
|
|
|
69
111
|
find: new RegExp(`^${name}$`),
|
|
70
112
|
replacement: replacement('index')
|
|
71
113
|
},
|
|
114
|
+
...Object.keys(subpackagesMap).reduce((pre, cur: string) => {
|
|
115
|
+
if (subpackagesMap[cur].length) {
|
|
116
|
+
pre.push({
|
|
117
|
+
find: new RegExp(`^${getPackageName(cur)}$`),
|
|
118
|
+
replacement: replacement(cur, true)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return pre;
|
|
122
|
+
}, [] as any),
|
|
72
123
|
{
|
|
73
124
|
|
|
74
125
|
find: new RegExp(`^${name}-(.*?)$`),
|
|
@@ -82,15 +133,35 @@ export default defineConfig({
|
|
|
82
133
|
name: 'vite-plugin-virtual-html',
|
|
83
134
|
configureServer(server: ViteDevServer) {
|
|
84
135
|
server.middlewares.use(async (req, res, next) => {
|
|
85
|
-
|
|
136
|
+
if (res.writableEnded) {
|
|
137
|
+
return next();
|
|
138
|
+
}
|
|
139
|
+
if (req.url!.includes('html-proxy&')) {
|
|
140
|
+
return next();
|
|
141
|
+
}
|
|
86
142
|
|
|
87
|
-
|
|
143
|
+
let url = req.url?.replace(/[?#].*$/s, '') || '';
|
|
144
|
+
if (url === '/') return res.end(html);
|
|
88
145
|
|
|
89
|
-
|
|
146
|
+
// 文件已存在,这样xxx.png可以被获取,真实路径的.ts,.html都可以被获取
|
|
147
|
+
if (fs.existsSync(path.join(cwd, url))) {
|
|
90
148
|
return next();
|
|
91
149
|
}
|
|
92
150
|
|
|
93
|
-
|
|
151
|
+
let vHtml = await getVirtualHtml(url);
|
|
152
|
+
if (
|
|
153
|
+
(url?.endsWith('.html') || vHtml)
|
|
154
|
+
&& req.headers['sec-fetch-dest'] !== 'script'
|
|
155
|
+
) {
|
|
156
|
+
if (!vHtml) {
|
|
157
|
+
return res.end(html);
|
|
158
|
+
}
|
|
159
|
+
vHtml = await server.transformIndexHtml(url, vHtml, req.originalUrl);
|
|
160
|
+
res.end(vHtml);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
next();
|
|
94
165
|
});
|
|
95
166
|
}
|
|
96
167
|
}
|