Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "command-pack-picomatch-hoist-false",
"version": "1.0.0",
"type": "module",
"devDependencies": {
"typescript": "^6.0.3",
"vite-plus": "0.1.23"
},
"packageManager": "pnpm@11.5.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hoist: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
> vp install --ignore-scripts
> vp pack src/index.ts 2>&1
ℹ entry: src/index.ts
ℹ Build start
ℹ dist/index.mjs <variable> kB │ gzip: <variable> kB
ℹ 1 files, total: <variable> kB
✔ Build complete in <variable>ms
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"linkCheckoutPackages": true,
"commands": [
{
"command": "vp install --ignore-scripts",
"ignoreOutput": true,
"timeout": 120000
},
"vp pack src/index.ts 2>&1"
]
}
105 changes: 66 additions & 39 deletions packages/core/build-support/find-create-require.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,11 @@ export async function replaceThirdPartyCjsRequires(
const thirdPartyModules = new Set<string>();

// Find all createRequire patterns and their require calls
const results = [
findCreateRequireInStaticImports(ast),
findCreateRequireInGlobalModule(ast),
].filter((result): result is { requireVarName: string; calls: RequireCall[] } => Boolean(result));
const results = [findCreateRequireInStaticImports(ast), findCreateRequireInGlobalModule(ast)];

// Collect all third-party require calls
const replacements: RequireCall[] = [];
for (const { calls } of results) {
for (const calls of results) {
for (const call of calls) {
if (isThirdPartyModule(call.module)) {
const parts = call.module.split('/');
Expand Down Expand Up @@ -106,21 +103,51 @@ function findRequireCalls(ast: ParseResult, requireVarName: string): RequireCall
return;
}

// Extract the first argument (module specifier)
if (node.arguments.length === 0) {
return;
const call = getLiteralRequireArgument(node);
if (call) {
calls.push(call);
}
const arg = node.arguments[0];
if (arg.type !== 'Literal') {
},
});

visitor.visit(ast.program);
return calls;
}

function getLiteralRequireArgument(node: CallExpression): RequireCall | undefined {
if (node.arguments.length === 0) {
return undefined;
}
const arg = node.arguments[0];
if (arg.type !== 'Literal') {
return undefined;
}
const value = (arg as { value: unknown; start: number; end: number }).value;
if (typeof value !== 'string') {
return undefined;
}
return {
module: value,
start: arg.start,
end: arg.end,
};
}
Comment thread
fengmk2 marked this conversation as resolved.

function findDirectCreateRequireCalls(
ast: ParseResult,
isCreateRequireCall: (node: CallExpression) => boolean,
): RequireCall[] {
const calls: RequireCall[] = [];

const visitor = new Visitor({
CallExpression(node: CallExpression) {
if (node.callee.type !== 'CallExpression' || !isCreateRequireCall(node.callee)) {
return;
}
const value = (arg as { value: unknown; start: number; end: number }).value;
if (typeof value === 'string') {
calls.push({
module: value,
start: arg.start,
end: arg.end,
});

const call = getLiteralRequireArgument(node);
if (call) {
calls.push(call);
}
},
});
Expand All @@ -133,24 +160,22 @@ function findRequireCalls(ast: ParseResult, requireVarName: string): RequireCall
* Find createRequire from static imports and return the require variable name + all require calls
* Handles: `import { createRequire } from "node:module"` then `const require = createRequire(...)`
*/
function findCreateRequireInStaticImports(
ast: ParseResult,
): { requireVarName: string; calls: RequireCall[] } | undefined {
function findCreateRequireInStaticImports(ast: ParseResult): RequireCall[] {
// Find import from 'module' or 'node:module'
const importFromModule = ast.module.staticImports.find((imt) => {
const { value } = imt.moduleRequest;
return value === 'node:module' || value === 'module';
});
if (!importFromModule) {
return undefined;
return [];
}

// Find the createRequire import entry
const createRequireEntry = importFromModule.entries.find((entry) => {
return entry.importName.name === 'createRequire';
});
if (!createRequireEntry) {
return undefined;
return [];
}

const createRequireLocalName = createRequireEntry.localName.value;
Expand All @@ -174,14 +199,14 @@ function findCreateRequireInStaticImports(
});
varVisitor.visit(ast.program);

if (!requireVarName) {
return undefined;
}

// Find all calls to the require variable
const calls = findRequireCalls(ast, requireVarName);
const calls = requireVarName ? findRequireCalls(ast, requireVarName) : [];
calls.push(
...findDirectCreateRequireCalls(ast, (node) => {
return node.callee.type === 'Identifier' && node.callee.name === createRequireLocalName;
}),
);

return { requireVarName, calls };
return calls;
}

// Helper to check if an expression is `process` or `globalThis.process`
Expand Down Expand Up @@ -240,9 +265,7 @@ function isGetBuiltinModuleCall(expr: Expression): boolean {
* Handles: `const require = globalThis.process.getBuiltinModule("module").createRequire(import.meta.url)`
* Or: `const require = process.getBuiltinModule("module").createRequire(import.meta.url)`
*/
function findCreateRequireInGlobalModule(
ast: ParseResult,
): { requireVarName: string; calls: RequireCall[] } | undefined {
function findCreateRequireInGlobalModule(ast: ParseResult): RequireCall[] {
let requireVarName: string | undefined;

const visitor = new Visitor({
Expand Down Expand Up @@ -276,12 +299,16 @@ function findCreateRequireInGlobalModule(

visitor.visit(ast.program);

if (!requireVarName) {
return undefined;
}

// Find all calls to the require variable
const calls = findRequireCalls(ast, requireVarName);
const calls = requireVarName ? findRequireCalls(ast, requireVarName) : [];
calls.push(
...findDirectCreateRequireCalls(ast, (node) => {
if (node.callee.type !== 'MemberExpression' || node.callee.computed) {
return false;
}
const callee = node.callee as StaticMemberExpression;
return callee.property.name === 'createRequire' && isGetBuiltinModuleCall(callee.object);
}),
);

return { requireVarName, calls };
return calls;
}
Loading