@dimina/compiler 1.0.12-beta.9 → 1.0.12

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.
@@ -1,23 +1,13 @@
1
1
  import fs from "node:fs";
2
2
  import { resolve, sep } from "node:path";
3
3
  import { isMainThread, parentPort } from "node:worker_threads";
4
- import babel from "@babel/core";
5
- import _traverse from "@babel/traverse";
6
- import types from "@babel/types";
4
+ import { parseSync } from "oxc-parser";
5
+ import { walk } from "oxc-walker";
6
+ import { transformSync } from "oxc-transform";
7
+ import MagicString from "magic-string";
7
8
  import { transform } from "esbuild";
8
9
  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";
11
- const traverse = _traverse.default ? _traverse.default : _traverse;
12
- const BABEL_TRANSFORM_CONFIG = {
13
- comments: false,
14
- configFile: false,
15
- babelrc: false,
16
- plugins: [
17
- // 将 ES6 import/export 转换为 CommonJS
18
- transformModulesCommonjs
19
- ]
20
- };
10
+ import { r as resetStoreInfo, e as getTargetPath, i as hasCompileInfo, a as getContentByPath, j as getAppConfigInfo, g as getComponent, f as getWorkPath } from "../env-QQjdhY-G.js";
21
11
  const processedModules = /* @__PURE__ */ new Set();
22
12
  if (!isMainThread) {
23
13
  parentPort.on("message", async ({ pages, storeInfo }) => {
@@ -95,15 +85,15 @@ ${module.code}
95
85
  async function compileJS(pages, root, mainCompileRes, progress) {
96
86
  const compileRes = [];
97
87
  if (!root) {
98
- buildJSByPath(root, { path: "app" }, compileRes, mainCompileRes, false);
88
+ await buildJSByPath(root, { path: "app" }, compileRes, mainCompileRes, false);
99
89
  }
100
- pages.forEach((page) => {
101
- buildJSByPath(root, page, compileRes, mainCompileRes, true);
90
+ for (const page of pages) {
91
+ await buildJSByPath(root, page, compileRes, mainCompileRes, true);
102
92
  progress.completedTasks++;
103
- });
93
+ }
104
94
  return compileRes;
105
95
  }
106
- function buildJSByPath(packageName, module, compileRes, mainCompileRes, addExtra, depthChain = [], putMain = false) {
96
+ async function buildJSByPath(packageName, module, compileRes, mainCompileRes, addExtra, depthChain = [], putMain = false) {
107
97
  const currentPath = module.path;
108
98
  if (depthChain.includes(currentPath)) {
109
99
  console.warn("[logic]", `检测到循环依赖: ${[...depthChain, currentPath].join(" -> ")}`);
@@ -141,7 +131,8 @@ function buildJSByPath(packageName, module, compileRes, mainCompileRes, addExtra
141
131
  const result = ts.transpileModule(sourceCode, {
142
132
  compilerOptions: {
143
133
  target: ts.ScriptTarget.ES2020,
144
- module: ts.ModuleKind.CommonJS,
134
+ module: ts.ModuleKind.ESNext,
135
+ // 保持 ES6 模块语法,让 oxc-transform 后续处理
145
136
  strict: false,
146
137
  esModuleInterop: true,
147
138
  skipLibCheck: true
@@ -153,16 +144,20 @@ function buildJSByPath(packageName, module, compileRes, mainCompileRes, addExtra
153
144
  jsCode = sourceCode;
154
145
  }
155
146
  }
156
- const ast = babel.parseSync(jsCode);
157
- const addedArgs = types.objectExpression([
158
- types.objectProperty(types.identifier("path"), types.stringLiteral(module.path))
159
- ]);
147
+ const parseResult = parseSync(modulePath, jsCode, {
148
+ sourceType: "module",
149
+ lang: modulePath.endsWith(".ts") ? "ts" : "js"
150
+ });
151
+ const ast = parseResult.program;
152
+ const s = new MagicString(jsCode);
153
+ const extraInfo = {
154
+ path: module.path
155
+ };
160
156
  if (module.component) {
161
- const component = types.objectProperty(types.identifier("component"), types.booleanLiteral(true));
162
- addedArgs.properties.push(component);
157
+ extraInfo.component = true;
163
158
  }
164
159
  if (module.usingComponents) {
165
- const components = types.objectProperty(types.identifier("usingComponents"), types.objectExpression([]));
160
+ const componentsObj = {};
166
161
  const allSubPackages = getAppConfigInfo().subPackages;
167
162
  for (const [name, path] of Object.entries(module.usingComponents)) {
168
163
  let toMainSubPackage = true;
@@ -181,84 +176,184 @@ function buildJSByPath(packageName, module, compileRes, mainCompileRes, addExtra
181
176
  if (!componentModule) {
182
177
  continue;
183
178
  }
184
- buildJSByPath(packageName, componentModule, compileRes, mainCompileRes, true, depthChain, toMainSubPackage);
185
- const props = types.objectProperty(types.identifier(`'${name}'`), types.stringLiteral(path));
186
- components.value.properties.push(props);
179
+ await buildJSByPath(packageName, componentModule, compileRes, mainCompileRes, true, depthChain, toMainSubPackage);
180
+ componentsObj[name] = path;
187
181
  }
188
- addedArgs.properties.push(components);
182
+ extraInfo.usingComponents = componentsObj;
189
183
  }
190
184
  if (addExtra) {
191
- ast.program.body.splice(0, 0, getExtraInfoStatement("this", addedArgs));
185
+ const extraInfoCode = `globalThis.__extraInfo = ${JSON.stringify(extraInfo)};
186
+ `;
187
+ s.prepend(extraInfoCode);
192
188
  }
193
189
  if (putMain) {
194
190
  mainCompileRes.push(compileInfo);
195
191
  } else {
196
192
  compileRes.push(compileInfo);
197
193
  }
198
- traverse(ast, {
199
- CallExpression(ap) {
200
- if (ap.node.callee.name === "require" || ap.node.callee.object?.name === "require") {
201
- const requirePath = ap.node.arguments[0].value;
202
- if (requirePath) {
203
- const requireFullPath = resolve(modulePath, `../${requirePath}`);
204
- let id = requireFullPath.split(`${getWorkPath()}${sep}`)[1];
205
- id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
206
- if (!id.startsWith("/")) {
207
- id = "/" + id;
208
- }
209
- ap.node.arguments[0] = types.stringLiteral(id);
210
- if (!processedModules.has(packageName + id)) {
211
- buildJSByPath(packageName, { path: id }, compileRes, mainCompileRes, false, depthChain);
194
+ const pathReplacements = [];
195
+ const dependenciesToProcess = [];
196
+ walk(ast, {
197
+ enter(node, parent) {
198
+ if (node.type === "CallExpression") {
199
+ const isRequire = node.callee.type === "Identifier" && node.callee.name === "require";
200
+ const isRequireProperty = node.callee.type === "MemberExpression" && node.callee.object?.type === "Identifier" && node.callee.object?.name === "require";
201
+ if ((isRequire || isRequireProperty) && node.arguments.length > 0 && (node.arguments[0].type === "StringLiteral" || node.arguments[0].type === "Literal")) {
202
+ const arg = node.arguments[0];
203
+ const requirePath = arg.value;
204
+ if (requirePath) {
205
+ let id;
206
+ if (requirePath.startsWith("@") || requirePath.startsWith("miniprogram_npm/")) {
207
+ if (requirePath.startsWith("@")) {
208
+ id = `/miniprogram_npm/${requirePath}`;
209
+ } else {
210
+ id = requirePath.startsWith("/") ? requirePath : `/${requirePath}`;
211
+ }
212
+ } else {
213
+ const requireFullPath = resolve(modulePath, `../${requirePath}`);
214
+ id = requireFullPath.split(`${getWorkPath()}${sep}`)[1];
215
+ id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
216
+ if (!id.startsWith("/")) {
217
+ id = "/" + id;
218
+ }
219
+ }
220
+ {
221
+ pathReplacements.push({
222
+ start: arg.start,
223
+ end: arg.end,
224
+ newValue: id
225
+ });
226
+ if (!processedModules.has(packageName + id)) {
227
+ dependenciesToProcess.push(id);
228
+ }
229
+ }
212
230
  }
213
231
  }
214
232
  }
215
- },
216
- ImportDeclaration(ap) {
217
- const importPath = ap.node.source.value;
218
- if (importPath) {
219
- let id;
220
- let shouldProcess = false;
221
- if (importPath.startsWith("@") || importPath.startsWith("miniprogram_npm/")) {
222
- if (importPath.startsWith("@")) {
223
- id = `/miniprogram_npm/${importPath}`;
233
+ if (node.type === "ImportDeclaration") {
234
+ const importPath = node.source.value;
235
+ if (importPath) {
236
+ let id;
237
+ let shouldProcess = false;
238
+ if (importPath.startsWith("@") || importPath.startsWith("miniprogram_npm/")) {
239
+ if (importPath.startsWith("@")) {
240
+ id = `/miniprogram_npm/${importPath}`;
241
+ } else {
242
+ id = importPath.startsWith("/") ? importPath : `/${importPath}`;
243
+ }
244
+ shouldProcess = true;
245
+ } else if (importPath.startsWith("./") || importPath.startsWith("../") || !importPath.startsWith("/")) {
246
+ const importFullPath = resolve(modulePath, `../${importPath}`);
247
+ id = importFullPath.split(`${getWorkPath()}${sep}`)[1];
248
+ id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
249
+ if (!id.startsWith("/")) {
250
+ id = "/" + id;
251
+ }
252
+ shouldProcess = true;
224
253
  } else {
225
- id = importPath.startsWith("/") ? importPath : `/${importPath}`;
254
+ id = importPath;
255
+ shouldProcess = true;
226
256
  }
227
- shouldProcess = true;
228
- } else if (importPath.startsWith("./") || importPath.startsWith("../") || !importPath.startsWith("/")) {
229
- const importFullPath = resolve(modulePath, `../${importPath}`);
230
- id = importFullPath.split(`${getWorkPath()}${sep}`)[1];
231
- id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
232
- if (!id.startsWith("/")) {
233
- id = "/" + id;
257
+ if (shouldProcess) {
258
+ pathReplacements.push({
259
+ start: node.source.start,
260
+ end: node.source.end,
261
+ newValue: id
262
+ });
263
+ if (!processedModules.has(packageName + id)) {
264
+ dependenciesToProcess.push(id);
265
+ }
234
266
  }
235
- shouldProcess = true;
236
- } else {
237
- id = importPath;
238
- shouldProcess = true;
239
267
  }
240
- if (shouldProcess) {
241
- ap.node.source = types.stringLiteral(id);
242
- if (!processedModules.has(packageName + id)) {
243
- buildJSByPath(packageName, { path: id }, compileRes, mainCompileRes, false, depthChain);
268
+ }
269
+ }
270
+ });
271
+ for (const depId of dependenciesToProcess) {
272
+ await buildJSByPath(packageName, { path: depId }, compileRes, mainCompileRes, false, depthChain);
273
+ }
274
+ for (const replacement of pathReplacements.reverse()) {
275
+ s.overwrite(replacement.start, replacement.end, `'${replacement.newValue}'`);
276
+ }
277
+ const modifiedCode = s.toString();
278
+ let transformedCode = modifiedCode;
279
+ if (modulePath.endsWith(".ts") || modulePath.endsWith(".tsx")) {
280
+ try {
281
+ const result = transformSync(modulePath, modifiedCode, {
282
+ sourceType: "module",
283
+ lang: modulePath.endsWith(".tsx") ? "tsx" : "ts",
284
+ target: "es2020",
285
+ typescript: {
286
+ onlyRemoveTypeImports: true
287
+ }
288
+ });
289
+ transformedCode = result.code;
290
+ } catch (error) {
291
+ console.error(`[logic] oxc-transform 转换失败 ${modulePath}:`, error.message);
292
+ transformedCode = modifiedCode;
293
+ }
294
+ }
295
+ try {
296
+ const esbuildResult = await transform(transformedCode, {
297
+ format: "cjs",
298
+ target: "es2020",
299
+ platform: "neutral",
300
+ loader: "js"
301
+ });
302
+ const esbuildCode = esbuildResult.code;
303
+ const esbuildAst = parseSync(modulePath, esbuildCode, {
304
+ sourceType: "module",
305
+ lang: "js"
306
+ });
307
+ const postEsbuildReplacements = [];
308
+ walk(esbuildAst.program, {
309
+ enter(node) {
310
+ if (node.type === "CallExpression") {
311
+ const isRequire = node.callee.type === "Identifier" && node.callee.name === "require";
312
+ const isRequireProperty = node.callee.type === "MemberExpression" && node.callee.object?.type === "Identifier" && node.callee.object?.name === "require";
313
+ if ((isRequire || isRequireProperty) && node.arguments.length > 0 && (node.arguments[0].type === "StringLiteral" || node.arguments[0].type === "Literal")) {
314
+ const arg = node.arguments[0];
315
+ const requirePath = arg.value;
316
+ if (requirePath && (requirePath.startsWith("./") || requirePath.startsWith("../"))) {
317
+ let id;
318
+ if (requirePath.startsWith("@") || requirePath.startsWith("miniprogram_npm/")) {
319
+ if (requirePath.startsWith("@")) {
320
+ id = `/miniprogram_npm/${requirePath}`;
321
+ } else {
322
+ id = requirePath.startsWith("/") ? requirePath : `/${requirePath}`;
323
+ }
324
+ } else {
325
+ const requireFullPath = resolve(modulePath, `../${requirePath}`);
326
+ id = requireFullPath.split(`${getWorkPath()}${sep}`)[1];
327
+ id = id.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
328
+ if (!id.startsWith("/")) {
329
+ id = "/" + id;
330
+ }
331
+ }
332
+ postEsbuildReplacements.push({
333
+ start: arg.start,
334
+ end: arg.end,
335
+ newValue: id
336
+ });
337
+ }
244
338
  }
245
339
  }
246
340
  }
341
+ });
342
+ if (postEsbuildReplacements.length > 0) {
343
+ const finalMagicString = new MagicString(esbuildCode);
344
+ for (const replacement of postEsbuildReplacements.reverse()) {
345
+ finalMagicString.overwrite(replacement.start, replacement.end, `"${replacement.newValue}"`);
346
+ }
347
+ compileInfo.code = finalMagicString.toString();
348
+ } else {
349
+ compileInfo.code = esbuildCode;
247
350
  }
248
- });
249
- const { code } = babel.transformFromAstSync(ast, "", BABEL_TRANSFORM_CONFIG);
250
- compileInfo.code = code;
351
+ } catch (error) {
352
+ console.error(`[logic] esbuild 转换失败 ${modulePath}:`, error.message);
353
+ compileInfo.code = transformedCode;
354
+ }
251
355
  processedModules.add(packageName + currentPath);
252
356
  }
253
- function getExtraInfoStatement(type, addedArgs) {
254
- const propertyAssignment = types.objectProperty(types.identifier("__extraInfo"), addedArgs);
255
- const assignmentExpression = types.assignmentExpression(
256
- "=",
257
- types.memberExpression(types.identifier("globalThis"), propertyAssignment.key),
258
- propertyAssignment.value
259
- );
260
- return types.expressionStatement(assignmentExpression);
261
- }
262
357
  function getJSAbsolutePath(modulePath) {
263
358
  const workPath = getWorkPath();
264
359
  const fileTypes = [".js", ".ts"];
@@ -186,17 +186,18 @@ async function enhanceCSS(module2) {
186
186
  });
187
187
  const cssCode = ast.toResult().css;
188
188
  const moduleId = module2.id;
189
- const code = compilerSfc.compileStyle({
189
+ const scopedCode = compilerSfc.compileStyle({
190
190
  source: cssCode,
191
191
  id: moduleId,
192
192
  scoped: !!moduleId
193
193
  }).code;
194
- const res = await postcss([autoprefixer({ overrideBrowserslist: ["cover 99.5%"] }), cssnano()]).process(code, {
195
- from: void 0
196
- // 未指定输入源文件路径
197
- });
194
+ const cleanedCode = await removeBaseComponentScope(scopedCode, moduleId);
195
+ const res = await postcss([
196
+ autoprefixer({ overrideBrowserslist: ["cover 99.5%"] }),
197
+ cssnano()
198
+ ]).process(cleanedCode, { from: void 0 });
198
199
  const importCss = (await Promise.all(promises)).filter(Boolean).join("");
199
- const result = importCss ? importCss + res.css : res.css;
200
+ const result = importCss + res.css;
200
201
  compileRes.set(module2.path, result);
201
202
  return result;
202
203
  }
@@ -210,6 +211,26 @@ function getAbsolutePath(modulePath) {
210
211
  }
211
212
  }
212
213
  }
214
+ async function removeBaseComponentScope(css, moduleId) {
215
+ if (!moduleId) return css;
216
+ const ast = postcss.parse(css);
217
+ const scopeAttrName = `data-v-${moduleId}`;
218
+ ast.walkRules((rule) => {
219
+ const hasBaseComponent = env.tagWhiteList.some(
220
+ (tag) => rule.selector.includes(`.dd-${tag}`)
221
+ );
222
+ if (hasBaseComponent && rule.selector.includes(scopeAttrName)) {
223
+ rule.selector = selectorParser((selectors) => {
224
+ selectors.walkAttributes((attr) => {
225
+ if (attr.attribute === scopeAttrName) {
226
+ attr.remove();
227
+ }
228
+ });
229
+ }).processSync(rule.selector);
230
+ }
231
+ });
232
+ return ast.toResult().css;
233
+ }
213
234
  function ensureImportSemicolons(css) {
214
235
  return css.replace(/@import[^;\n]*$/gm, (match) => {
215
236
  return match.endsWith(";") ? match : `${match};`;
@@ -221,3 +242,4 @@ function processHostSelector(selector, moduleId) {
221
242
  exports.compileSS = compileSS;
222
243
  exports.ensureImportSemicolons = ensureImportSemicolons;
223
244
  exports.processHostSelector = processHostSelector;
245
+ exports.removeBaseComponentScope = removeBaseComponentScope;
@@ -8,7 +8,7 @@ import less from "less";
8
8
  import postcss from "postcss";
9
9
  import selectorParser from "postcss-selector-parser";
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";
11
+ import { r as resetStoreInfo, e as getTargetPath, g as getComponent, a as getContentByPath, h as tagWhiteList, c as collectAssets, d as getAppId, f as getWorkPath, t as transformRpx } from "../env-QQjdhY-G.js";
12
12
  const fileType = [".wxss", ".ddss", ".less", ".scss", ".sass"];
13
13
  const compileRes = /* @__PURE__ */ new Map();
14
14
  if (!isMainThread) {
@@ -167,17 +167,18 @@ async function enhanceCSS(module) {
167
167
  });
168
168
  const cssCode = ast.toResult().css;
169
169
  const moduleId = module.id;
170
- const code = compileStyle({
170
+ const scopedCode = compileStyle({
171
171
  source: cssCode,
172
172
  id: moduleId,
173
173
  scoped: !!moduleId
174
174
  }).code;
175
- const res = await postcss([autoprefixer({ overrideBrowserslist: ["cover 99.5%"] }), cssnano()]).process(code, {
176
- from: void 0
177
- // 未指定输入源文件路径
178
- });
175
+ const cleanedCode = await removeBaseComponentScope(scopedCode, moduleId);
176
+ const res = await postcss([
177
+ autoprefixer({ overrideBrowserslist: ["cover 99.5%"] }),
178
+ cssnano()
179
+ ]).process(cleanedCode, { from: void 0 });
179
180
  const importCss = (await Promise.all(promises)).filter(Boolean).join("");
180
- const result = importCss ? importCss + res.css : res.css;
181
+ const result = importCss + res.css;
181
182
  compileRes.set(module.path, result);
182
183
  return result;
183
184
  }
@@ -191,6 +192,26 @@ function getAbsolutePath(modulePath) {
191
192
  }
192
193
  }
193
194
  }
195
+ async function removeBaseComponentScope(css, moduleId) {
196
+ if (!moduleId) return css;
197
+ const ast = postcss.parse(css);
198
+ const scopeAttrName = `data-v-${moduleId}`;
199
+ ast.walkRules((rule) => {
200
+ const hasBaseComponent = tagWhiteList.some(
201
+ (tag) => rule.selector.includes(`.dd-${tag}`)
202
+ );
203
+ if (hasBaseComponent && rule.selector.includes(scopeAttrName)) {
204
+ rule.selector = selectorParser((selectors) => {
205
+ selectors.walkAttributes((attr) => {
206
+ if (attr.attribute === scopeAttrName) {
207
+ attr.remove();
208
+ }
209
+ });
210
+ }).processSync(rule.selector);
211
+ }
212
+ });
213
+ return ast.toResult().css;
214
+ }
194
215
  function ensureImportSemicolons(css) {
195
216
  return css.replace(/@import[^;\n]*$/gm, (match) => {
196
217
  return match.endsWith(";") ? match : `${match};`;
@@ -202,5 +223,6 @@ function processHostSelector(selector, moduleId) {
202
223
  export {
203
224
  compileSS,
204
225
  ensureImportSemicolons,
205
- processHostSelector
226
+ processHostSelector,
227
+ removeBaseComponentScope
206
228
  };