@dimina/compiler 1.0.7 → 1.0.8
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 +48 -0
- package/dist/core/logic-compiler.cjs +90 -13
- package/dist/core/logic-compiler.js +90 -13
- package/dist/core/style-compiler.cjs +59 -6
- package/dist/core/style-compiler.js +43 -7
- package/dist/core/view-compiler.cjs +538 -69
- package/dist/core/view-compiler.js +538 -69
- package/dist/env-Cmen1qwy.cjs +543 -0
- package/dist/env-Csj3AHY4.js +544 -0
- package/dist/index.cjs +195 -1
- package/dist/index.js +195 -1
- package/package.json +15 -11
- package/dist/env-CGYKCSjT.cjs +0 -322
- package/dist/env-fkuCnng-.js +0 -323
package/README.md
CHANGED
|
@@ -98,11 +98,59 @@ dmcc build --no-app-id-dir
|
|
|
98
98
|
|
|
99
99
|
```txt
|
|
100
100
|
app.js, index.js -> logic.js (逻辑文件)
|
|
101
|
+
app.ts, index.ts -> logic.js (TypeScript 逻辑文件)
|
|
101
102
|
index.wxml -> view.js (视图文件)
|
|
102
103
|
app.wxss, index.wxss -> style.css (样式文件)
|
|
104
|
+
app.less, index.less -> style.css (Less 样式文件)
|
|
105
|
+
app.scss, index.scss -> style.css (SCSS 样式文件)
|
|
106
|
+
app.sass, index.sass -> style.css (Sass 样式文件)
|
|
103
107
|
app.json, index.json -> config.json (配置文件)
|
|
108
|
+
miniprogram_npm/ -> npm包构建 (npm组件支持)
|
|
104
109
|
```
|
|
105
110
|
|
|
111
|
+
### TypeScript、Less 和 SCSS 支持
|
|
112
|
+
|
|
113
|
+
编译器现已支持现代前端开发工具:
|
|
114
|
+
|
|
115
|
+
- ✅ **TypeScript 支持**: `.ts` 文件自动编译为 JavaScript
|
|
116
|
+
- ✅ **ES6 Import 语句**: 支持相对路径、npm 包和绝对路径导入
|
|
117
|
+
- ✅ **Less 支持**: `.less` 文件编译为 CSS,支持变量、mixin 和嵌套
|
|
118
|
+
- ✅ **SCSS/Sass 支持**: `.scss` 和 `.sass` 文件编译为 CSS
|
|
119
|
+
- ✅ **错误处理**: 编译失败时自动回退,不中断构建流程
|
|
120
|
+
- ✅ **向后兼容**: 完全兼容现有的 `.js` 和 `.wxss` 文件
|
|
121
|
+
|
|
122
|
+
#### 支持的文件类型
|
|
123
|
+
|
|
124
|
+
**逻辑文件查找顺序**: `.js` → `.ts`
|
|
125
|
+
**样式文件查找顺序**: `.wxss` → `.ddss` → `.less` → `.scss` → `.sass`
|
|
126
|
+
|
|
127
|
+
详细使用说明请参考:[TypeScript、Less 和 SCSS 支持文档](./docs/typescript-less-scss-support.md)
|
|
128
|
+
|
|
129
|
+
### npm 组件支持
|
|
130
|
+
|
|
131
|
+
编译器现已支持微信小程序的 npm 包功能,遵循微信官方的 npm 支持规范:
|
|
132
|
+
|
|
133
|
+
- ✅ 支持 `miniprogram_npm` 目录中的组件解析
|
|
134
|
+
- ✅ 按照微信小程序寻址顺序查找组件
|
|
135
|
+
- ✅ 自动构建和复制 npm 包文件
|
|
136
|
+
- ✅ 支持组件依赖关系处理
|
|
137
|
+
- ✅ 缓存机制提升编译性能
|
|
138
|
+
- ✅ 兼容现有的相对路径组件引用
|
|
139
|
+
|
|
140
|
+
#### npm 组件使用示例
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
// pages/index/index.json
|
|
144
|
+
{
|
|
145
|
+
"usingComponents": {
|
|
146
|
+
"lib-button": "lib-weapp/button",
|
|
147
|
+
"custom-component": "./components/custom"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
详细使用说明请参考:[npm 支持文档](./docs/npm-support.md)
|
|
153
|
+
|
|
106
154
|
### 编译产物目录结构
|
|
107
155
|
|
|
108
156
|
编译后,默认会在目标目录生成以小程序 id 命名的文件夹,项目结构如下:
|
|
@@ -7,7 +7,9 @@ const babel = require("@babel/core");
|
|
|
7
7
|
const _traverse = require("@babel/traverse");
|
|
8
8
|
const types = require("@babel/types");
|
|
9
9
|
const esbuild = require("esbuild");
|
|
10
|
-
const
|
|
10
|
+
const ts = require("typescript");
|
|
11
|
+
const transformModulesCommonjs = require("@babel/plugin-transform-modules-commonjs");
|
|
12
|
+
const env = require("../env-Cmen1qwy.cjs");
|
|
11
13
|
const traverse = _traverse.default ? _traverse.default : _traverse;
|
|
12
14
|
const processedModules = /* @__PURE__ */ new Set();
|
|
13
15
|
if (!node_worker_threads.isMainThread) {
|
|
@@ -117,9 +119,35 @@ function buildJSByPath(packageName, module2, compileRes, mainCompileRes, addExtr
|
|
|
117
119
|
code: ""
|
|
118
120
|
};
|
|
119
121
|
const src = module2.path.startsWith("/") ? module2.path : `/${module2.path}`;
|
|
120
|
-
const modulePath =
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
const modulePath = getJSAbsolutePath(src);
|
|
123
|
+
if (!modulePath) {
|
|
124
|
+
console.warn("[logic]", `找不到模块文件: ${src}`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const sourceCode = env.getContentByPath(modulePath);
|
|
128
|
+
if (!sourceCode) {
|
|
129
|
+
console.warn("[logic]", `无法读取模块文件: ${modulePath}`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
let jsCode = sourceCode;
|
|
133
|
+
if (modulePath.endsWith(".ts")) {
|
|
134
|
+
try {
|
|
135
|
+
const result = ts.transpileModule(sourceCode, {
|
|
136
|
+
compilerOptions: {
|
|
137
|
+
target: ts.ScriptTarget.ES2020,
|
|
138
|
+
module: ts.ModuleKind.CommonJS,
|
|
139
|
+
strict: false,
|
|
140
|
+
esModuleInterop: true,
|
|
141
|
+
skipLibCheck: true
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
jsCode = result.outputText;
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error(`[logic] TypeScript 编译失败 ${modulePath}:`, error.message);
|
|
147
|
+
jsCode = sourceCode;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const ast = babel.parseSync(jsCode);
|
|
123
151
|
const addedArgs = types.objectExpression([
|
|
124
152
|
types.objectProperty(types.identifier("path"), types.stringLiteral(module2.path))
|
|
125
153
|
]);
|
|
@@ -167,31 +195,80 @@ function buildJSByPath(packageName, module2, compileRes, mainCompileRes, addExtr
|
|
|
167
195
|
const requirePath = ap.node.arguments[0].value;
|
|
168
196
|
if (requirePath) {
|
|
169
197
|
const requireFullPath = path.resolve(modulePath, `../${requirePath}`);
|
|
170
|
-
|
|
198
|
+
let id = requireFullPath.split(`${env.getWorkPath()}${path.sep}`)[1];
|
|
199
|
+
id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
|
|
200
|
+
if (!id.startsWith("/")) {
|
|
201
|
+
id = "/" + id;
|
|
202
|
+
}
|
|
171
203
|
ap.node.arguments[0] = types.stringLiteral(id);
|
|
172
204
|
if (!processedModules.has(packageName + id)) {
|
|
173
205
|
buildJSByPath(packageName, { path: id }, compileRes, mainCompileRes, false, depthChain);
|
|
174
206
|
}
|
|
175
207
|
}
|
|
176
208
|
}
|
|
209
|
+
},
|
|
210
|
+
ImportDeclaration(ap) {
|
|
211
|
+
const importPath = ap.node.source.value;
|
|
212
|
+
if (importPath) {
|
|
213
|
+
let id;
|
|
214
|
+
let shouldProcess = false;
|
|
215
|
+
if (importPath.startsWith("@") || importPath.startsWith("miniprogram_npm/")) {
|
|
216
|
+
if (importPath.startsWith("@")) {
|
|
217
|
+
id = `/miniprogram_npm/${importPath}`;
|
|
218
|
+
} else {
|
|
219
|
+
id = importPath.startsWith("/") ? importPath : `/${importPath}`;
|
|
220
|
+
}
|
|
221
|
+
shouldProcess = true;
|
|
222
|
+
} else if (importPath.startsWith("./") || importPath.startsWith("../") || !importPath.startsWith("/")) {
|
|
223
|
+
const importFullPath = path.resolve(modulePath, `../${importPath}`);
|
|
224
|
+
id = importFullPath.split(`${env.getWorkPath()}${path.sep}`)[1];
|
|
225
|
+
id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
|
|
226
|
+
if (!id.startsWith("/")) {
|
|
227
|
+
id = "/" + id;
|
|
228
|
+
}
|
|
229
|
+
shouldProcess = true;
|
|
230
|
+
} else {
|
|
231
|
+
id = importPath;
|
|
232
|
+
shouldProcess = true;
|
|
233
|
+
}
|
|
234
|
+
if (shouldProcess) {
|
|
235
|
+
ap.node.source = types.stringLiteral(id);
|
|
236
|
+
if (!processedModules.has(packageName + id)) {
|
|
237
|
+
buildJSByPath(packageName, { path: id }, compileRes, mainCompileRes, false, depthChain);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
177
241
|
}
|
|
178
242
|
});
|
|
179
243
|
const { code } = babel.transformFromAstSync(ast, "", {
|
|
180
|
-
comments: false
|
|
244
|
+
comments: false,
|
|
245
|
+
plugins: [
|
|
246
|
+
// 将 ES6 import/export 转换为 CommonJS
|
|
247
|
+
transformModulesCommonjs
|
|
248
|
+
]
|
|
181
249
|
});
|
|
182
250
|
compileInfo.code = code;
|
|
183
251
|
processedModules.add(packageName + currentPath);
|
|
184
252
|
}
|
|
185
253
|
function getExtraInfoStatement(type, addedArgs) {
|
|
186
254
|
const propertyAssignment = types.objectProperty(types.identifier("__extraInfo"), addedArgs);
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
propertyAssignment.value
|
|
192
|
-
)
|
|
255
|
+
const assignmentExpression = types.assignmentExpression(
|
|
256
|
+
"=",
|
|
257
|
+
types.memberExpression(types.identifier("globalThis"), propertyAssignment.key),
|
|
258
|
+
propertyAssignment.value
|
|
193
259
|
);
|
|
194
|
-
return
|
|
260
|
+
return types.expressionStatement(assignmentExpression);
|
|
261
|
+
}
|
|
262
|
+
function getJSAbsolutePath(modulePath) {
|
|
263
|
+
const workPath = env.getWorkPath();
|
|
264
|
+
const fileTypes = [".js", ".ts"];
|
|
265
|
+
for (const ext of fileTypes) {
|
|
266
|
+
const fullPath = `${workPath}${modulePath}${ext}`;
|
|
267
|
+
if (fs.existsSync(fullPath)) {
|
|
268
|
+
return fullPath;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
195
272
|
}
|
|
196
273
|
exports.buildJSByPath = buildJSByPath;
|
|
197
274
|
exports.compileJS = compileJS;
|
|
@@ -5,7 +5,9 @@ import babel from "@babel/core";
|
|
|
5
5
|
import _traverse from "@babel/traverse";
|
|
6
6
|
import types from "@babel/types";
|
|
7
7
|
import { transform } from "esbuild";
|
|
8
|
-
import
|
|
8
|
+
import ts from "typescript";
|
|
9
|
+
import transformModulesCommonjs from "@babel/plugin-transform-modules-commonjs";
|
|
10
|
+
import { r as resetStoreInfo, g as getTargetPath, i as hasCompileInfo, b as getContentByPath, j as getAppConfigInfo, a as getComponent, d as getWorkPath } from "../env-Csj3AHY4.js";
|
|
9
11
|
const traverse = _traverse.default ? _traverse.default : _traverse;
|
|
10
12
|
const processedModules = /* @__PURE__ */ new Set();
|
|
11
13
|
if (!isMainThread) {
|
|
@@ -115,9 +117,35 @@ function buildJSByPath(packageName, module, compileRes, mainCompileRes, addExtra
|
|
|
115
117
|
code: ""
|
|
116
118
|
};
|
|
117
119
|
const src = module.path.startsWith("/") ? module.path : `/${module.path}`;
|
|
118
|
-
const modulePath =
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
const modulePath = getJSAbsolutePath(src);
|
|
121
|
+
if (!modulePath) {
|
|
122
|
+
console.warn("[logic]", `找不到模块文件: ${src}`);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const sourceCode = getContentByPath(modulePath);
|
|
126
|
+
if (!sourceCode) {
|
|
127
|
+
console.warn("[logic]", `无法读取模块文件: ${modulePath}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
let jsCode = sourceCode;
|
|
131
|
+
if (modulePath.endsWith(".ts")) {
|
|
132
|
+
try {
|
|
133
|
+
const result = ts.transpileModule(sourceCode, {
|
|
134
|
+
compilerOptions: {
|
|
135
|
+
target: ts.ScriptTarget.ES2020,
|
|
136
|
+
module: ts.ModuleKind.CommonJS,
|
|
137
|
+
strict: false,
|
|
138
|
+
esModuleInterop: true,
|
|
139
|
+
skipLibCheck: true
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
jsCode = result.outputText;
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error(`[logic] TypeScript 编译失败 ${modulePath}:`, error.message);
|
|
145
|
+
jsCode = sourceCode;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const ast = babel.parseSync(jsCode);
|
|
121
149
|
const addedArgs = types.objectExpression([
|
|
122
150
|
types.objectProperty(types.identifier("path"), types.stringLiteral(module.path))
|
|
123
151
|
]);
|
|
@@ -165,31 +193,80 @@ function buildJSByPath(packageName, module, compileRes, mainCompileRes, addExtra
|
|
|
165
193
|
const requirePath = ap.node.arguments[0].value;
|
|
166
194
|
if (requirePath) {
|
|
167
195
|
const requireFullPath = resolve(modulePath, `../${requirePath}`);
|
|
168
|
-
|
|
196
|
+
let id = requireFullPath.split(`${getWorkPath()}${sep}`)[1];
|
|
197
|
+
id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
|
|
198
|
+
if (!id.startsWith("/")) {
|
|
199
|
+
id = "/" + id;
|
|
200
|
+
}
|
|
169
201
|
ap.node.arguments[0] = types.stringLiteral(id);
|
|
170
202
|
if (!processedModules.has(packageName + id)) {
|
|
171
203
|
buildJSByPath(packageName, { path: id }, compileRes, mainCompileRes, false, depthChain);
|
|
172
204
|
}
|
|
173
205
|
}
|
|
174
206
|
}
|
|
207
|
+
},
|
|
208
|
+
ImportDeclaration(ap) {
|
|
209
|
+
const importPath = ap.node.source.value;
|
|
210
|
+
if (importPath) {
|
|
211
|
+
let id;
|
|
212
|
+
let shouldProcess = false;
|
|
213
|
+
if (importPath.startsWith("@") || importPath.startsWith("miniprogram_npm/")) {
|
|
214
|
+
if (importPath.startsWith("@")) {
|
|
215
|
+
id = `/miniprogram_npm/${importPath}`;
|
|
216
|
+
} else {
|
|
217
|
+
id = importPath.startsWith("/") ? importPath : `/${importPath}`;
|
|
218
|
+
}
|
|
219
|
+
shouldProcess = true;
|
|
220
|
+
} else if (importPath.startsWith("./") || importPath.startsWith("../") || !importPath.startsWith("/")) {
|
|
221
|
+
const importFullPath = resolve(modulePath, `../${importPath}`);
|
|
222
|
+
id = importFullPath.split(`${getWorkPath()}${sep}`)[1];
|
|
223
|
+
id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
|
|
224
|
+
if (!id.startsWith("/")) {
|
|
225
|
+
id = "/" + id;
|
|
226
|
+
}
|
|
227
|
+
shouldProcess = true;
|
|
228
|
+
} else {
|
|
229
|
+
id = importPath;
|
|
230
|
+
shouldProcess = true;
|
|
231
|
+
}
|
|
232
|
+
if (shouldProcess) {
|
|
233
|
+
ap.node.source = types.stringLiteral(id);
|
|
234
|
+
if (!processedModules.has(packageName + id)) {
|
|
235
|
+
buildJSByPath(packageName, { path: id }, compileRes, mainCompileRes, false, depthChain);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
175
239
|
}
|
|
176
240
|
});
|
|
177
241
|
const { code } = babel.transformFromAstSync(ast, "", {
|
|
178
|
-
comments: false
|
|
242
|
+
comments: false,
|
|
243
|
+
plugins: [
|
|
244
|
+
// 将 ES6 import/export 转换为 CommonJS
|
|
245
|
+
transformModulesCommonjs
|
|
246
|
+
]
|
|
179
247
|
});
|
|
180
248
|
compileInfo.code = code;
|
|
181
249
|
processedModules.add(packageName + currentPath);
|
|
182
250
|
}
|
|
183
251
|
function getExtraInfoStatement(type, addedArgs) {
|
|
184
252
|
const propertyAssignment = types.objectProperty(types.identifier("__extraInfo"), addedArgs);
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
propertyAssignment.value
|
|
190
|
-
)
|
|
253
|
+
const assignmentExpression = types.assignmentExpression(
|
|
254
|
+
"=",
|
|
255
|
+
types.memberExpression(types.identifier("globalThis"), propertyAssignment.key),
|
|
256
|
+
propertyAssignment.value
|
|
191
257
|
);
|
|
192
|
-
return
|
|
258
|
+
return types.expressionStatement(assignmentExpression);
|
|
259
|
+
}
|
|
260
|
+
function getJSAbsolutePath(modulePath) {
|
|
261
|
+
const workPath = getWorkPath();
|
|
262
|
+
const fileTypes = [".js", ".ts"];
|
|
263
|
+
for (const ext of fileTypes) {
|
|
264
|
+
const fullPath = `${workPath}${modulePath}${ext}`;
|
|
265
|
+
if (fs.existsSync(fullPath)) {
|
|
266
|
+
return fullPath;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
193
270
|
}
|
|
194
271
|
export {
|
|
195
272
|
buildJSByPath,
|
|
@@ -6,10 +6,29 @@ const node_worker_threads = require("node:worker_threads");
|
|
|
6
6
|
const compilerSfc = require("@vue/compiler-sfc");
|
|
7
7
|
const autoprefixer = require("autoprefixer");
|
|
8
8
|
const cssnano = require("cssnano");
|
|
9
|
+
const less = require("less");
|
|
9
10
|
const postcss = require("postcss");
|
|
10
11
|
const selectorParser = require("postcss-selector-parser");
|
|
11
|
-
const
|
|
12
|
-
const
|
|
12
|
+
const sass = require("sass");
|
|
13
|
+
const env = require("../env-Cmen1qwy.cjs");
|
|
14
|
+
function _interopNamespaceDefault(e) {
|
|
15
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
16
|
+
if (e) {
|
|
17
|
+
for (const k in e) {
|
|
18
|
+
if (k !== "default") {
|
|
19
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: () => e[k]
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
n.default = e;
|
|
28
|
+
return Object.freeze(n);
|
|
29
|
+
}
|
|
30
|
+
const sass__namespace = /* @__PURE__ */ _interopNamespaceDefault(sass);
|
|
31
|
+
const fileType = [".wxss", ".ddss", ".less", ".scss", ".sass"];
|
|
13
32
|
const compileRes = /* @__PURE__ */ new Map();
|
|
14
33
|
if (!node_worker_threads.isMainThread) {
|
|
15
34
|
node_worker_threads.parentPort.on("message", async ({ pages, storeInfo }) => {
|
|
@@ -90,8 +109,34 @@ async function enhanceCSS(module2) {
|
|
|
90
109
|
if (compileRes.has(absolutePath)) {
|
|
91
110
|
return compileRes.get(absolutePath);
|
|
92
111
|
}
|
|
93
|
-
|
|
94
|
-
const
|
|
112
|
+
let processedCSS = inputCSS;
|
|
113
|
+
const ext = path.extname(absolutePath).toLowerCase();
|
|
114
|
+
try {
|
|
115
|
+
if (ext === ".less") {
|
|
116
|
+
const result2 = await less.render(inputCSS, {
|
|
117
|
+
filename: absolutePath,
|
|
118
|
+
paths: [path.dirname(absolutePath)]
|
|
119
|
+
});
|
|
120
|
+
processedCSS = result2.css;
|
|
121
|
+
} else if (ext === ".scss" || ext === ".sass") {
|
|
122
|
+
const result2 = sass__namespace.compileString(inputCSS, {
|
|
123
|
+
loadPaths: [path.dirname(absolutePath)],
|
|
124
|
+
syntax: ext === ".sass" ? "indented" : "scss"
|
|
125
|
+
});
|
|
126
|
+
processedCSS = result2.css;
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error(`[style] 预处理器编译失败 ${absolutePath}:`, error.message);
|
|
130
|
+
processedCSS = inputCSS;
|
|
131
|
+
}
|
|
132
|
+
const fixedCSS = ensureImportSemicolons(processedCSS);
|
|
133
|
+
let ast;
|
|
134
|
+
try {
|
|
135
|
+
ast = postcss.parse(fixedCSS);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error(`[style] PostCSS 解析失败 ${absolutePath}:`, error.message);
|
|
138
|
+
return "";
|
|
139
|
+
}
|
|
95
140
|
const promises = [];
|
|
96
141
|
ast.walk(async (node) => {
|
|
97
142
|
if (node.type === "atrule" && node.name === "import") {
|
|
@@ -103,6 +148,9 @@ async function enhanceCSS(module2) {
|
|
|
103
148
|
if (node.selector.includes("::v-deep")) {
|
|
104
149
|
node.selector = node.selector.replace(/::v-deep\s+(\S[^{]*)/g, ":deep($1)");
|
|
105
150
|
}
|
|
151
|
+
if (node.selector.includes(":host")) {
|
|
152
|
+
node.selector = processHostSelector(node.selector, module2.id);
|
|
153
|
+
}
|
|
106
154
|
node.selector = selectorParser((selectors) => {
|
|
107
155
|
selectors.walkTags((tag) => {
|
|
108
156
|
if (env.tagWhiteList.includes(tag.value)) {
|
|
@@ -128,10 +176,11 @@ async function enhanceCSS(module2) {
|
|
|
128
176
|
}
|
|
129
177
|
});
|
|
130
178
|
const cssCode = ast.toResult().css;
|
|
179
|
+
const moduleId = module2.id;
|
|
131
180
|
const code = compilerSfc.compileStyle({
|
|
132
181
|
source: cssCode,
|
|
133
|
-
id:
|
|
134
|
-
scoped: !!
|
|
182
|
+
id: moduleId,
|
|
183
|
+
scoped: !!moduleId
|
|
135
184
|
}).code;
|
|
136
185
|
const res = await postcss([autoprefixer({ overrideBrowserslist: ["cover 99.5%"] }), cssnano()]).process(code, {
|
|
137
186
|
from: void 0
|
|
@@ -157,5 +206,9 @@ function ensureImportSemicolons(css) {
|
|
|
157
206
|
return match.endsWith(";") ? match : `${match};`;
|
|
158
207
|
});
|
|
159
208
|
}
|
|
209
|
+
function processHostSelector(selector, moduleId) {
|
|
210
|
+
return selector.replace(/^:host$/, `[data-v-${moduleId}]`).replace(/:host\(([^)]+)\)/g, `[data-v-${moduleId}]$1`).replace(/:host\s+/g, `[data-v-${moduleId}] `).replace(/:host(?=\.|#|:)/g, `[data-v-${moduleId}]`);
|
|
211
|
+
}
|
|
160
212
|
exports.compileSS = compileSS;
|
|
161
213
|
exports.ensureImportSemicolons = ensureImportSemicolons;
|
|
214
|
+
exports.processHostSelector = processHostSelector;
|
|
@@ -4,10 +4,12 @@ import { isMainThread, parentPort } from "node:worker_threads";
|
|
|
4
4
|
import { compileStyle } from "@vue/compiler-sfc";
|
|
5
5
|
import autoprefixer from "autoprefixer";
|
|
6
6
|
import cssnano from "cssnano";
|
|
7
|
+
import less from "less";
|
|
7
8
|
import postcss from "postcss";
|
|
8
9
|
import selectorParser from "postcss-selector-parser";
|
|
9
|
-
import
|
|
10
|
-
|
|
10
|
+
import * as sass from "sass";
|
|
11
|
+
import { r as resetStoreInfo, g as getTargetPath, a as getComponent, b as getContentByPath, h as tagWhiteList, e as collectAssets, f as getAppId, d as getWorkPath, t as transformRpx } from "../env-Csj3AHY4.js";
|
|
12
|
+
const fileType = [".wxss", ".ddss", ".less", ".scss", ".sass"];
|
|
11
13
|
const compileRes = /* @__PURE__ */ new Map();
|
|
12
14
|
if (!isMainThread) {
|
|
13
15
|
parentPort.on("message", async ({ pages, storeInfo }) => {
|
|
@@ -88,8 +90,34 @@ async function enhanceCSS(module) {
|
|
|
88
90
|
if (compileRes.has(absolutePath)) {
|
|
89
91
|
return compileRes.get(absolutePath);
|
|
90
92
|
}
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
+
let processedCSS = inputCSS;
|
|
94
|
+
const ext = path.extname(absolutePath).toLowerCase();
|
|
95
|
+
try {
|
|
96
|
+
if (ext === ".less") {
|
|
97
|
+
const result2 = await less.render(inputCSS, {
|
|
98
|
+
filename: absolutePath,
|
|
99
|
+
paths: [path.dirname(absolutePath)]
|
|
100
|
+
});
|
|
101
|
+
processedCSS = result2.css;
|
|
102
|
+
} else if (ext === ".scss" || ext === ".sass") {
|
|
103
|
+
const result2 = sass.compileString(inputCSS, {
|
|
104
|
+
loadPaths: [path.dirname(absolutePath)],
|
|
105
|
+
syntax: ext === ".sass" ? "indented" : "scss"
|
|
106
|
+
});
|
|
107
|
+
processedCSS = result2.css;
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.error(`[style] 预处理器编译失败 ${absolutePath}:`, error.message);
|
|
111
|
+
processedCSS = inputCSS;
|
|
112
|
+
}
|
|
113
|
+
const fixedCSS = ensureImportSemicolons(processedCSS);
|
|
114
|
+
let ast;
|
|
115
|
+
try {
|
|
116
|
+
ast = postcss.parse(fixedCSS);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error(`[style] PostCSS 解析失败 ${absolutePath}:`, error.message);
|
|
119
|
+
return "";
|
|
120
|
+
}
|
|
93
121
|
const promises = [];
|
|
94
122
|
ast.walk(async (node) => {
|
|
95
123
|
if (node.type === "atrule" && node.name === "import") {
|
|
@@ -101,6 +129,9 @@ async function enhanceCSS(module) {
|
|
|
101
129
|
if (node.selector.includes("::v-deep")) {
|
|
102
130
|
node.selector = node.selector.replace(/::v-deep\s+(\S[^{]*)/g, ":deep($1)");
|
|
103
131
|
}
|
|
132
|
+
if (node.selector.includes(":host")) {
|
|
133
|
+
node.selector = processHostSelector(node.selector, module.id);
|
|
134
|
+
}
|
|
104
135
|
node.selector = selectorParser((selectors) => {
|
|
105
136
|
selectors.walkTags((tag) => {
|
|
106
137
|
if (tagWhiteList.includes(tag.value)) {
|
|
@@ -126,10 +157,11 @@ async function enhanceCSS(module) {
|
|
|
126
157
|
}
|
|
127
158
|
});
|
|
128
159
|
const cssCode = ast.toResult().css;
|
|
160
|
+
const moduleId = module.id;
|
|
129
161
|
const code = compileStyle({
|
|
130
162
|
source: cssCode,
|
|
131
|
-
id:
|
|
132
|
-
scoped: !!
|
|
163
|
+
id: moduleId,
|
|
164
|
+
scoped: !!moduleId
|
|
133
165
|
}).code;
|
|
134
166
|
const res = await postcss([autoprefixer({ overrideBrowserslist: ["cover 99.5%"] }), cssnano()]).process(code, {
|
|
135
167
|
from: void 0
|
|
@@ -155,7 +187,11 @@ function ensureImportSemicolons(css) {
|
|
|
155
187
|
return match.endsWith(";") ? match : `${match};`;
|
|
156
188
|
});
|
|
157
189
|
}
|
|
190
|
+
function processHostSelector(selector, moduleId) {
|
|
191
|
+
return selector.replace(/^:host$/, `[data-v-${moduleId}]`).replace(/:host\(([^)]+)\)/g, `[data-v-${moduleId}]$1`).replace(/:host\s+/g, `[data-v-${moduleId}] `).replace(/:host(?=\.|#|:)/g, `[data-v-${moduleId}]`);
|
|
192
|
+
}
|
|
158
193
|
export {
|
|
159
194
|
compileSS,
|
|
160
|
-
ensureImportSemicolons
|
|
195
|
+
ensureImportSemicolons,
|
|
196
|
+
processHostSelector
|
|
161
197
|
};
|