@dev-to/react-plugin 1.0.2 → 1.1.3
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 +3 -2
- package/bin/dev-to.js +179 -0
- package/dist/876.js +3 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +81 -0
- package/dist/index.js +6 -8
- package/dist/types.d.ts +1 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ export default defineConfig({
|
|
|
33
33
|
|
|
34
34
|
### components 参数形态
|
|
35
35
|
|
|
36
|
-
- `devToReactPlugin()`:通配符模式(默认 `'*': '/'`),便于开发;但 `vite build --mode lib
|
|
36
|
+
- `devToReactPlugin()`:通配符模式(默认 `'*': '/'`),便于开发;但 `dev-to build`(等价于 `vite build --mode lib`)需要显式 componentName。
|
|
37
37
|
- `devToReactPlugin('MyCard')`:字符串快捷模式,等价于 `{ MyCard: '/' }`。
|
|
38
38
|
- `devToReactPlugin({ MyCard: 'src/MyCard.tsx' })`:显式映射(推荐,且 lib 构建必须)。
|
|
39
39
|
|
|
@@ -61,7 +61,8 @@ export default defineConfig({
|
|
|
61
61
|
|
|
62
62
|
## 生产构建(Library Mode)
|
|
63
63
|
|
|
64
|
-
执行 `vite build --mode lib
|
|
64
|
+
执行 `dev-to build`(等价于 `vite build --mode lib`)时,插件会按 `components` 参数为每个组件产出一个 UMD bundle,默认输出到 `dist/<component>/`。
|
|
65
|
+
支持透传 Vite build 参数,例如:`dev-to build --sourcemap --outDir dist-lib`。
|
|
65
66
|
|
|
66
67
|
> 提示:`'*': '/'` 的通配符模式仅适合开发;lib 构建请显式列出组件名。
|
|
67
68
|
|
package/bin/dev-to.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process'
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import { createRequire } from 'node:module'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import process from 'node:process'
|
|
7
|
+
|
|
8
|
+
const { console } = globalThis
|
|
9
|
+
|
|
10
|
+
const args = process.argv.slice(2)
|
|
11
|
+
|
|
12
|
+
if (args.length === 0 || args[0] === '-h' || args[0] === '--help') {
|
|
13
|
+
printHelp()
|
|
14
|
+
process.exit(0)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const command = args[0]
|
|
18
|
+
if (command !== 'build') {
|
|
19
|
+
console.error(`Unknown command: ${command}`)
|
|
20
|
+
printHelp()
|
|
21
|
+
process.exit(1)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { args: forwardedArgs, removed } = stripModeArgs(args.slice(1))
|
|
25
|
+
if (removed) {
|
|
26
|
+
console.error('Note: --mode is managed by dev-to (lib). The provided mode is ignored.')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const result = spawnSync(
|
|
30
|
+
process.execPath,
|
|
31
|
+
[resolveViteBin(), 'build', '--mode', 'lib', ...forwardedArgs],
|
|
32
|
+
{ stdio: 'inherit' },
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
if (result.error) {
|
|
36
|
+
console.error(`Failed to run Vite: ${result.error.message}`)
|
|
37
|
+
process.exit(1)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
process.exit(result.status ?? 1)
|
|
41
|
+
|
|
42
|
+
function stripModeArgs(userArgs) {
|
|
43
|
+
const cleaned = []
|
|
44
|
+
let removed = false
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < userArgs.length; i += 1) {
|
|
47
|
+
const arg = userArgs[i]
|
|
48
|
+
if (arg === '--') {
|
|
49
|
+
continue
|
|
50
|
+
}
|
|
51
|
+
if (arg === '--mode' || arg === '-m') {
|
|
52
|
+
removed = true
|
|
53
|
+
i += 1
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
if (arg.startsWith('--mode=')) {
|
|
57
|
+
removed = true
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
if (arg.startsWith('-m') && arg.length > 2) {
|
|
61
|
+
removed = true
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
64
|
+
cleaned.push(arg)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { args: cleaned, removed }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function resolveViteBin() {
|
|
71
|
+
const require = createRequire(import.meta.url)
|
|
72
|
+
const searchPaths = [process.cwd(), path.join(process.cwd(), 'node_modules')]
|
|
73
|
+
|
|
74
|
+
const resolved = resolvePath(require, 'vite/bin/vite.js', searchPaths)
|
|
75
|
+
if (resolved) {
|
|
76
|
+
return resolved
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const viteEntry = resolvePath(require, 'vite', searchPaths)
|
|
80
|
+
if (viteEntry) {
|
|
81
|
+
const viteRoot = findPackageRoot(viteEntry)
|
|
82
|
+
if (viteRoot) {
|
|
83
|
+
const binPath = resolveBinFromPackage(viteRoot)
|
|
84
|
+
if (binPath) {
|
|
85
|
+
return binPath
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
console.error('Vite is not installed or could not be resolved. Please add it to devDependencies.')
|
|
91
|
+
process.exit(1)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function resolvePath(require, specifier, searchPaths) {
|
|
95
|
+
for (const base of searchPaths) {
|
|
96
|
+
try {
|
|
97
|
+
return require.resolve(specifier, { paths: [base] })
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Try next path.
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
return require.resolve(specifier)
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function findPackageRoot(startPath) {
|
|
113
|
+
let current = path.dirname(startPath)
|
|
114
|
+
while (true) {
|
|
115
|
+
const pkgPath = path.join(current, 'package.json')
|
|
116
|
+
if (fs.existsSync(pkgPath)) {
|
|
117
|
+
try {
|
|
118
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
|
|
119
|
+
if (pkg && pkg.name === 'vite') {
|
|
120
|
+
return current
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Keep walking up.
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const parent = path.dirname(current)
|
|
129
|
+
if (parent === current) {
|
|
130
|
+
break
|
|
131
|
+
}
|
|
132
|
+
current = parent
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function resolveBinFromPackage(pkgRoot) {
|
|
139
|
+
const pkgPath = path.join(pkgRoot, 'package.json')
|
|
140
|
+
if (!fs.existsSync(pkgPath)) {
|
|
141
|
+
return null
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
|
|
146
|
+
if (pkg && pkg.bin) {
|
|
147
|
+
const binEntry = typeof pkg.bin === 'string'
|
|
148
|
+
? pkg.bin
|
|
149
|
+
: pkg.bin.vite || pkg.bin['vite']
|
|
150
|
+
if (binEntry) {
|
|
151
|
+
const binPath = path.resolve(pkgRoot, binEntry)
|
|
152
|
+
if (fs.existsSync(binPath)) {
|
|
153
|
+
return binPath
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Fall back to default path.
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const fallback = path.resolve(pkgRoot, 'bin', 'vite.js')
|
|
163
|
+
return fs.existsSync(fallback) ? fallback : null
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function printHelp() {
|
|
167
|
+
console.log(
|
|
168
|
+
[
|
|
169
|
+
'dev-to <command>',
|
|
170
|
+
'',
|
|
171
|
+
'Commands:',
|
|
172
|
+
' build Run "vite build --mode lib" and forward extra args.',
|
|
173
|
+
'',
|
|
174
|
+
'Examples:',
|
|
175
|
+
' dev-to build',
|
|
176
|
+
' dev-to build --sourcemap --outDir dist-lib',
|
|
177
|
+
].join('\n'),
|
|
178
|
+
)
|
|
179
|
+
}
|
package/dist/876.js
ADDED
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import node_process from "node:process";
|
|
3
|
+
import { createRequire, node_path, spawnSync } from "./876.js";
|
|
4
|
+
const args = node_process.argv.slice(2);
|
|
5
|
+
if (0 === args.length || '-h' === args[0] || '--help' === args[0]) {
|
|
6
|
+
printHelp();
|
|
7
|
+
node_process.exit(0);
|
|
8
|
+
}
|
|
9
|
+
const command = args[0];
|
|
10
|
+
if ('build' !== command) {
|
|
11
|
+
console.error(`Unknown command: ${command}`);
|
|
12
|
+
printHelp();
|
|
13
|
+
node_process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const { args: forwardedArgs, removed: cli_removed } = stripModeArgs(args.slice(1));
|
|
16
|
+
if (cli_removed) console.error('Note: --mode is managed by dev-to (lib). The provided mode is ignored.');
|
|
17
|
+
const viteBin = resolveViteBin();
|
|
18
|
+
const result = spawnSync(node_process.execPath, [
|
|
19
|
+
viteBin,
|
|
20
|
+
'build',
|
|
21
|
+
'--mode',
|
|
22
|
+
'lib',
|
|
23
|
+
...forwardedArgs
|
|
24
|
+
], {
|
|
25
|
+
stdio: 'inherit'
|
|
26
|
+
});
|
|
27
|
+
if (result.error) {
|
|
28
|
+
console.error(`Failed to run Vite: ${result.error.message}`);
|
|
29
|
+
node_process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
node_process.exit(result.status ?? 1);
|
|
32
|
+
function stripModeArgs(userArgs) {
|
|
33
|
+
const cleaned = [];
|
|
34
|
+
let removed = false;
|
|
35
|
+
for(let i = 0; i < userArgs.length; i += 1){
|
|
36
|
+
const arg = userArgs[i];
|
|
37
|
+
if ('--' !== arg) {
|
|
38
|
+
if ('--mode' === arg || '-m' === arg) {
|
|
39
|
+
removed = true;
|
|
40
|
+
i += 1;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (arg.startsWith('--mode=')) {
|
|
44
|
+
removed = true;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (arg.startsWith('-m') && arg.length > 2) {
|
|
48
|
+
removed = true;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
cleaned.push(arg);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
args: cleaned,
|
|
56
|
+
removed
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function resolveViteBin() {
|
|
60
|
+
const require = createRequire(import.meta.url);
|
|
61
|
+
const searchPaths = [
|
|
62
|
+
node_process.cwd(),
|
|
63
|
+
node_path.join(node_process.cwd(), 'node_modules')
|
|
64
|
+
];
|
|
65
|
+
for (const base of searchPaths)try {
|
|
66
|
+
return require.resolve('vite/bin/vite.js', {
|
|
67
|
+
paths: [
|
|
68
|
+
base
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
} catch {}
|
|
72
|
+
try {
|
|
73
|
+
return require.resolve('vite/bin/vite.js');
|
|
74
|
+
} catch {
|
|
75
|
+
console.error('Vite is not installed. Please add it to devDependencies.');
|
|
76
|
+
node_process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function printHelp() {
|
|
80
|
+
console.log('dev-to <command>\n\nCommands:\n build Run "vite build --mode lib" and forward extra args.\n\nExamples:\n dev-to build\n dev-to build --sourcemap --outDir dist-lib');
|
|
81
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { DEV_TO_BASE_PATH, DEV_TO_DEBUG_HTML_PATH, DEV_TO_DEBUG_JSON_PATH, DEV_TO_DISCOVERY_PATH, DEV_TO_NAMESPACE, DEV_TO_REACT_BASE_PATH, DEV_TO_REACT_CONTRACT_KEY, DEV_TO_REACT_CONTRACT_PATH, DEV_TO_REACT_DEBUG_STATE_KEY, DEV_TO_REACT_DID_OPEN_BROWSER_KEY, DEV_TO_REACT_EVENT_FULL_RELOAD, DEV_TO_REACT_EVENT_HMR_UPDATE, DEV_TO_REACT_INIT_PATH, DEV_TO_REACT_LOADER_BASE_PATH, DEV_TO_REACT_LOADER_UMD_PATH, DEV_TO_REACT_NAMESPACE, DEV_TO_REACT_ORIGIN_KEY, DEV_TO_REACT_RESOLVE_ASSET_KEY, DEV_TO_REACT_RUNTIME_PATH } from "@dev-to/react-shared";
|
|
2
2
|
import node_fs from "node:fs";
|
|
3
|
-
import node_path from "node:path";
|
|
4
3
|
import picocolors from "picocolors";
|
|
5
4
|
import { mergeConfig } from "vite";
|
|
6
|
-
import { exec } from "node:child_process";
|
|
7
|
-
import { createRequire } from "node:module";
|
|
8
5
|
import { fileURLToPath } from "node:url";
|
|
9
6
|
import node_os from "node:os";
|
|
10
7
|
import typescript from "typescript";
|
|
8
|
+
import { exec, node_path, createRequire } from "./876.js";
|
|
11
9
|
const PLUGIN_NAME = `${DEV_TO_NAMESPACE}_${DEV_TO_REACT_NAMESPACE}`;
|
|
12
10
|
const constants_PLUGIN_LOG_PREFIX = `[${DEV_TO_NAMESPACE}:${DEV_TO_REACT_NAMESPACE}]`;
|
|
13
11
|
const STABLE_BASE_PATH = DEV_TO_BASE_PATH;
|
|
@@ -383,7 +381,7 @@ root.render(React.createElement(window.ComponentName, { prop1: <span class="str"
|
|
|
383
381
|
|
|
384
382
|
<div class="card">
|
|
385
383
|
<h3>📦 构建与部署</h3>
|
|
386
|
-
<p class="muted">执行 <code>vite build --mode lib</code
|
|
384
|
+
<p class="muted">执行 <code>dev-to build</code>(等价于 <code>vite build --mode lib</code>)将组件打包为 UMD 格式以供发布。</p>
|
|
387
385
|
|
|
388
386
|
<div class="build-grid">
|
|
389
387
|
<div class="build-card">
|
|
@@ -1326,7 +1324,7 @@ function installDebugTools(server, ctx, state) {
|
|
|
1326
1324
|
suggested: requestOrigin,
|
|
1327
1325
|
snippet: `localStorage.setItem('VITE_DEV_SERVER_ORIGIN', '${requestOrigin}'); location.reload();`,
|
|
1328
1326
|
libBuild: {
|
|
1329
|
-
command: '
|
|
1327
|
+
command: 'dev-to build',
|
|
1330
1328
|
env: {
|
|
1331
1329
|
DEV_TO_REACT_LIB_SECTION: libComponentExample
|
|
1332
1330
|
},
|
|
@@ -1353,7 +1351,7 @@ function installDebugTools(server, ctx, state) {
|
|
|
1353
1351
|
'宿主侧需设置 localStorage.VITE_DEV_SERVER_ORIGIN(可从 originCandidates 里选择一个可访问的 origin)。',
|
|
1354
1352
|
'components 参数的 key 必须与后端返回的 componentName 完全一致(严格匹配)。',
|
|
1355
1353
|
'Fast Refresh 关键:必须先 import init.js(安装 react-refresh preamble),再 import react-dom/client。',
|
|
1356
|
-
'如需产出可分发 UMD 包:使用 `vite build --mode lib
|
|
1354
|
+
'如需产出可分发 UMD 包:使用 `dev-to build`(等价于 `vite build --mode lib`,仅构建 components 指定的组件,输出到 dist/<component>/)。'
|
|
1357
1355
|
]
|
|
1358
1356
|
}, null, 2));
|
|
1359
1357
|
return;
|
|
@@ -1891,7 +1889,7 @@ function devToReactPlugin(components, options) {
|
|
|
1891
1889
|
if (1 === Object.keys(resolvedConfig.componentMap).length && '/' === resolvedConfig.componentMap['*']) {
|
|
1892
1890
|
const warn = server.config.logger?.warn?.bind(server.config.logger) ?? console.warn;
|
|
1893
1891
|
warn('');
|
|
1894
|
-
warn(`⚠️ ${constants_PLUGIN_LOG_PREFIX} No componentName configured. This works in dev mode but will fail in library build (--mode lib).`);
|
|
1892
|
+
warn(`⚠️ ${constants_PLUGIN_LOG_PREFIX} No componentName configured. This works in dev mode but will fail in library build (dev-to build / --mode lib).`);
|
|
1895
1893
|
warn(' Please use devToReactPlugin({ ComponentName: "src/ComponentName.tsx" }) or devToReactPlugin({ ComponentName: "/" }) to specify components.');
|
|
1896
1894
|
warn(' Or use wildcard: devToReactPlugin({ "*": "/" }) or devToReactPlugin("*")');
|
|
1897
1895
|
warn('');
|
|
@@ -1932,7 +1930,7 @@ function devToReactPlugin(components, options) {
|
|
|
1932
1930
|
}).css;
|
|
1933
1931
|
if (isLibBuild(env)) {
|
|
1934
1932
|
const actualNames = Object.keys(contract.dev.componentMap).filter((n)=>'*' !== n);
|
|
1935
|
-
if (0 === actualNames.length && !process.env.DEV_TO_REACT_LIB_SECTION) throw new Error(` ${constants_PLUGIN_LOG_PREFIX} Library build (--mode lib) requires at least one explicit componentName for identification and distribution.\nCurrent configuration is in "global fallback mode", which cannot determine build targets.\n\nPlease use one of the following to specify components:\n - devToReactPlugin('ComponentName')\n - devToReactPlugin({ ComponentName: '/' })\n - devToReactPlugin({ ComponentName: 'src/ComponentName.tsx' })\n\n💡 Tip: Wildcards are convenient for development, but explicit naming is required for production builds.`);
|
|
1933
|
+
if (0 === actualNames.length && !process.env.DEV_TO_REACT_LIB_SECTION) throw new Error(` ${constants_PLUGIN_LOG_PREFIX} Library build (dev-to build / --mode lib) requires at least one explicit componentName for identification and distribution.\nCurrent configuration is in "global fallback mode", which cannot determine build targets.\n\nPlease use one of the following to specify components:\n - devToReactPlugin('ComponentName')\n - devToReactPlugin({ ComponentName: '/' })\n - devToReactPlugin({ ComponentName: 'src/ComponentName.tsx' })\n\n💡 Tip: Wildcards are convenient for development, but explicit naming is required for production builds.`);
|
|
1936
1934
|
const isChild = '1' === process.env.DEV_TO_REACT_LIB_CHILD;
|
|
1937
1935
|
const buildTargets = resolveBuildTargets({
|
|
1938
1936
|
componentMap: contract.dev.componentMap,
|
package/dist/types.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface DevToReactPluginOptions {
|
|
|
31
31
|
*/
|
|
32
32
|
css?: CSSOptions | false;
|
|
33
33
|
/**
|
|
34
|
-
* Build configuration passed to Vite (only applies when running `vite build --mode lib`).
|
|
34
|
+
* Build configuration passed to Vite (only applies when running `dev-to build` / `vite build --mode lib`).
|
|
35
35
|
*
|
|
36
36
|
* Typical use cases:
|
|
37
37
|
* - Adjust asset inlining: `assetsInlineLimit`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev-to/react-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,8 +11,12 @@
|
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"dev-to": "./bin/dev-to.js"
|
|
16
|
+
},
|
|
14
17
|
"files": [
|
|
15
|
-
"dist"
|
|
18
|
+
"dist",
|
|
19
|
+
"bin"
|
|
16
20
|
],
|
|
17
21
|
"peerDependencies": {
|
|
18
22
|
"react": ">=18.0.0",
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
"dependencies": {
|
|
32
36
|
"picocolors": "^1.1.0",
|
|
33
37
|
"typescript": "^5.4.5",
|
|
34
|
-
"@dev-to/react-shared": "1.0.
|
|
38
|
+
"@dev-to/react-shared": "1.0.1"
|
|
35
39
|
},
|
|
36
40
|
"scripts": {
|
|
37
41
|
"build": "rslib build",
|