@infly/vue2-vite 1.0.0 → 1.0.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/bin/vue-cli-service.mjs +135 -135
- package/package.json +1 -1
- package/src/compat/assets.mjs +165 -165
- package/src/compat/html.mjs +1 -1
- package/src/compat/import-interop.mjs +2 -2
- package/src/compat/jsx.mjs +142 -142
- package/src/compat/mock.mjs +125 -125
- package/src/compat/require-context.mjs +1 -1
- package/src/compat/sass-export.mjs +112 -112
- package/src/config/discover.mjs +261 -261
- package/src/config/vue-cli-reader.mjs +1 -0
- package/src/factory/create-vite-config.mjs +7 -8
- package/src/factory/manual-chunks.mjs +1 -0
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sass :export 兼容插件
|
|
3
|
-
*
|
|
4
|
-
* 将 `import styles from "./file.scss"` 转换为 SCSS 导入 + 导出变量的 JS 对象。
|
|
5
|
-
* 从 @infly/libs/adapters/vue2/vite/index.js 迁移(95% 可复用)。
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import fs from 'node:fs';
|
|
9
|
-
import path from 'node:path';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 解析应用内的 SCSS 导入路径
|
|
13
|
-
*/
|
|
14
|
-
function resolveAppScssImport(importPath, importer, projectRoot) {
|
|
15
|
-
const cleanImporter = importer.replace(/[?#].*$/, '');
|
|
16
|
-
if (importPath.startsWith('@/')) {
|
|
17
|
-
return path.resolve(projectRoot, 'src', importPath.slice(2));
|
|
18
|
-
}
|
|
19
|
-
if (importPath.startsWith('./') || importPath.startsWith('../')) {
|
|
20
|
-
return path.resolve(path.dirname(cleanImporter), importPath);
|
|
21
|
-
}
|
|
22
|
-
if (path.isAbsolute(importPath)) return path.resolve(importPath);
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* 转换 import varName from "./file.scss" → import "./file.scss"; const varName = {...}
|
|
28
|
-
*
|
|
29
|
-
* @param {string} code - 源文件内容
|
|
30
|
-
* @param {string} importer - 导入方文件路径
|
|
31
|
-
* @param {object} options - { projectRoot, readFile? }
|
|
32
|
-
* @returns {string} 转换后的代码
|
|
33
|
-
*/
|
|
34
|
-
export function transformScssExportImports(code, importer, options) {
|
|
35
|
-
const { projectRoot, readFile = (file) => fs.readFileSync(file, 'utf8') } = options;
|
|
36
|
-
|
|
37
|
-
return code.replace(
|
|
38
|
-
/import\s+([\w$]+)\s+from\s+(["'])([^"'?]+\.scss)\2\s*;?/g,
|
|
39
|
-
(statement, binding, quote, importPath) => {
|
|
40
|
-
const resolved = resolveAppScssImport(importPath, importer, projectRoot);
|
|
41
|
-
if (!resolved) return statement;
|
|
42
|
-
|
|
43
|
-
let scss;
|
|
44
|
-
try {
|
|
45
|
-
scss = readFile(resolved);
|
|
46
|
-
} catch
|
|
47
|
-
return statement;
|
|
48
|
-
}
|
|
49
|
-
if (typeof scss !== 'string') return statement;
|
|
50
|
-
|
|
51
|
-
const exportBlock = scss.match(/:export\s*\{([\s\S]*?)\}/);
|
|
52
|
-
if (!exportBlock) return statement;
|
|
53
|
-
|
|
54
|
-
const variables = new Map();
|
|
55
|
-
for (const match of scss.matchAll(/^\s*\$([\w-]+)\s*:\s*([^;]+);/gm)) {
|
|
56
|
-
variables.set(match[1], match[2].trim());
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const exported = {};
|
|
60
|
-
for (const match of exportBlock[1].matchAll(/([\w-]+)\s*:\s*([^;]+);/g)) {
|
|
61
|
-
const rawValue = match[2].trim();
|
|
62
|
-
const variableName = rawValue.match(/^\$([\w-]+)$/);
|
|
63
|
-
exported[match[1]] = variableName && variables.has(variableName[1])
|
|
64
|
-
? variables.get(variableName[1])
|
|
65
|
-
: rawValue;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return `import ${quote}${importPath}${quote};\nconst ${binding} = ${JSON.stringify(exported)};`;
|
|
69
|
-
},
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 创建 SCSS :export 兼容 Vite 插件
|
|
75
|
-
*
|
|
76
|
-
* @param {string} projectRoot - 项目根目录
|
|
77
|
-
* @returns {import('vite').Plugin}
|
|
78
|
-
*/
|
|
79
|
-
export function createScssExportCompatPlugin(projectRoot) {
|
|
80
|
-
return {
|
|
81
|
-
name: 'infly-vue2:scss-export-compat',
|
|
82
|
-
enforce: 'pre',
|
|
83
|
-
transform(code, id) {
|
|
84
|
-
if (
|
|
85
|
-
id.includes('node_modules')
|
|
86
|
-
|| (!id.includes('.vue') && !/\.[cm]?[jt]sx?(?:[?#].*)?$/.test(id))
|
|
87
|
-
|| !/import\s+[\w$]+\s+from\s+["'][^"']+\.scss["']/.test(code)
|
|
88
|
-
) return null;
|
|
89
|
-
|
|
90
|
-
const transformed = transformScssExportImports(code, id, { projectRoot });
|
|
91
|
-
return transformed === code ? null : { code: transformed, map: null };
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* 将项目根目录添加到 Sass loadPaths
|
|
98
|
-
*
|
|
99
|
-
* @param {object} css - Vite CSS 配置对象
|
|
100
|
-
* @param {string} projectRoot
|
|
101
|
-
* @returns {object}
|
|
102
|
-
*/
|
|
103
|
-
export function addAppRootSassLoadPath(css, projectRoot) {
|
|
104
|
-
if (!css.preprocessorOptions) css.preprocessorOptions = {};
|
|
105
|
-
if (!css.preprocessorOptions.scss) css.preprocessorOptions.scss = {};
|
|
106
|
-
const loadPaths = css.preprocessorOptions.scss.loadPaths || [];
|
|
107
|
-
const resolvedProjectRoot = path.resolve(projectRoot);
|
|
108
|
-
css.preprocessorOptions.scss.loadPaths = loadPaths.includes(resolvedProjectRoot)
|
|
109
|
-
? loadPaths
|
|
110
|
-
: [...loadPaths, resolvedProjectRoot];
|
|
111
|
-
return css;
|
|
112
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Sass :export 兼容插件
|
|
3
|
+
*
|
|
4
|
+
* 将 `import styles from "./file.scss"` 转换为 SCSS 导入 + 导出变量的 JS 对象。
|
|
5
|
+
* 从 @infly/libs/adapters/vue2/vite/index.js 迁移(95% 可复用)。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 解析应用内的 SCSS 导入路径
|
|
13
|
+
*/
|
|
14
|
+
function resolveAppScssImport(importPath, importer, projectRoot) {
|
|
15
|
+
const cleanImporter = importer.replace(/[?#].*$/, '');
|
|
16
|
+
if (importPath.startsWith('@/')) {
|
|
17
|
+
return path.resolve(projectRoot, 'src', importPath.slice(2));
|
|
18
|
+
}
|
|
19
|
+
if (importPath.startsWith('./') || importPath.startsWith('../')) {
|
|
20
|
+
return path.resolve(path.dirname(cleanImporter), importPath);
|
|
21
|
+
}
|
|
22
|
+
if (path.isAbsolute(importPath)) return path.resolve(importPath);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 转换 import varName from "./file.scss" → import "./file.scss"; const varName = {...}
|
|
28
|
+
*
|
|
29
|
+
* @param {string} code - 源文件内容
|
|
30
|
+
* @param {string} importer - 导入方文件路径
|
|
31
|
+
* @param {object} options - { projectRoot, readFile? }
|
|
32
|
+
* @returns {string} 转换后的代码
|
|
33
|
+
*/
|
|
34
|
+
export function transformScssExportImports(code, importer, options) {
|
|
35
|
+
const { projectRoot, readFile = (file) => fs.readFileSync(file, 'utf8') } = options;
|
|
36
|
+
|
|
37
|
+
return code.replace(
|
|
38
|
+
/import\s+([\w$]+)\s+from\s+(["'])([^"'?]+\.scss)\2\s*;?/g,
|
|
39
|
+
(statement, binding, quote, importPath) => {
|
|
40
|
+
const resolved = resolveAppScssImport(importPath, importer, projectRoot);
|
|
41
|
+
if (!resolved) return statement;
|
|
42
|
+
|
|
43
|
+
let scss;
|
|
44
|
+
try {
|
|
45
|
+
scss = readFile(resolved);
|
|
46
|
+
} catch {
|
|
47
|
+
return statement;
|
|
48
|
+
}
|
|
49
|
+
if (typeof scss !== 'string') return statement;
|
|
50
|
+
|
|
51
|
+
const exportBlock = scss.match(/:export\s*\{([\s\S]*?)\}/);
|
|
52
|
+
if (!exportBlock) return statement;
|
|
53
|
+
|
|
54
|
+
const variables = new Map();
|
|
55
|
+
for (const match of scss.matchAll(/^\s*\$([\w-]+)\s*:\s*([^;]+);/gm)) {
|
|
56
|
+
variables.set(match[1], match[2].trim());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const exported = {};
|
|
60
|
+
for (const match of exportBlock[1].matchAll(/([\w-]+)\s*:\s*([^;]+);/g)) {
|
|
61
|
+
const rawValue = match[2].trim();
|
|
62
|
+
const variableName = rawValue.match(/^\$([\w-]+)$/);
|
|
63
|
+
exported[match[1]] = variableName && variables.has(variableName[1])
|
|
64
|
+
? variables.get(variableName[1])
|
|
65
|
+
: rawValue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return `import ${quote}${importPath}${quote};\nconst ${binding} = ${JSON.stringify(exported)};`;
|
|
69
|
+
},
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 创建 SCSS :export 兼容 Vite 插件
|
|
75
|
+
*
|
|
76
|
+
* @param {string} projectRoot - 项目根目录
|
|
77
|
+
* @returns {import('vite').Plugin}
|
|
78
|
+
*/
|
|
79
|
+
export function createScssExportCompatPlugin(projectRoot) {
|
|
80
|
+
return {
|
|
81
|
+
name: 'infly-vue2:scss-export-compat',
|
|
82
|
+
enforce: 'pre',
|
|
83
|
+
transform(code, id) {
|
|
84
|
+
if (
|
|
85
|
+
id.includes('node_modules')
|
|
86
|
+
|| (!id.includes('.vue') && !/\.[cm]?[jt]sx?(?:[?#].*)?$/.test(id))
|
|
87
|
+
|| !/import\s+[\w$]+\s+from\s+["'][^"']+\.scss["']/.test(code)
|
|
88
|
+
) return null;
|
|
89
|
+
|
|
90
|
+
const transformed = transformScssExportImports(code, id, { projectRoot });
|
|
91
|
+
return transformed === code ? null : { code: transformed, map: null };
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 将项目根目录添加到 Sass loadPaths
|
|
98
|
+
*
|
|
99
|
+
* @param {object} css - Vite CSS 配置对象
|
|
100
|
+
* @param {string} projectRoot
|
|
101
|
+
* @returns {object}
|
|
102
|
+
*/
|
|
103
|
+
export function addAppRootSassLoadPath(css, projectRoot) {
|
|
104
|
+
if (!css.preprocessorOptions) css.preprocessorOptions = {};
|
|
105
|
+
if (!css.preprocessorOptions.scss) css.preprocessorOptions.scss = {};
|
|
106
|
+
const loadPaths = css.preprocessorOptions.scss.loadPaths || [];
|
|
107
|
+
const resolvedProjectRoot = path.resolve(projectRoot);
|
|
108
|
+
css.preprocessorOptions.scss.loadPaths = loadPaths.includes(resolvedProjectRoot)
|
|
109
|
+
? loadPaths
|
|
110
|
+
: [...loadPaths, resolvedProjectRoot];
|
|
111
|
+
return css;
|
|
112
|
+
}
|