Skip to content

Commit cb579c8

Browse files
authored
fix(commonjs): Keep the shebang at the top of the file content (#1610)
1 parent 1caee89 commit cb579c8

File tree

5 files changed

+43
-6
lines changed

5 files changed

+43
-6
lines changed

packages/commonjs/src/index.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,16 @@ export default function commonjs(options = {}) {
271271
// entry suffix is just appended to not mess up relative external resolution
272272
if (id.endsWith(ENTRY_SUFFIX)) {
273273
const acutalId = id.slice(0, -ENTRY_SUFFIX.length);
274-
return getEntryProxy(acutalId, getDefaultIsModuleExports(acutalId), this.getModuleInfo);
274+
const {
275+
meta: { commonjs: commonjsMeta }
276+
} = this.getModuleInfo(acutalId);
277+
const shebang = commonjsMeta?.shebang ?? '';
278+
return getEntryProxy(
279+
acutalId,
280+
getDefaultIsModuleExports(acutalId),
281+
this.getModuleInfo,
282+
shebang
283+
);
275284
}
276285

277286
if (isWrappedId(id, ES_IMPORT_SUFFIX)) {

packages/commonjs/src/proxies.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export async function getStaticRequireProxy(id, requireReturnsDefault, loadModul
4444
return `export { default } from ${JSON.stringify(id)};`;
4545
}
4646

47-
export function getEntryProxy(id, defaultIsModuleExports, getModuleInfo) {
47+
export function getEntryProxy(id, defaultIsModuleExports, getModuleInfo, shebang) {
4848
const {
4949
meta: { commonjs: commonjsMeta },
5050
hasDefaultExport
@@ -55,9 +55,13 @@ export function getEntryProxy(id, defaultIsModuleExports, getModuleInfo) {
5555
if (hasDefaultExport) {
5656
code += `export { default } from ${stringifiedId};`;
5757
}
58-
return code;
58+
return shebang + code;
5959
}
60-
return getEsImportProxy(id, defaultIsModuleExports);
60+
const result = getEsImportProxy(id, defaultIsModuleExports);
61+
return {
62+
...result,
63+
code: shebang + result.code
64+
};
6165
}
6266

6367
export function getEsImportProxy(id, defaultIsModuleExports) {

packages/commonjs/src/transform-commonjs.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,13 @@ export default async function transformCommonjs(
478478
magicString.remove(0, commentEnd).trim();
479479
}
480480

481+
let shebang = '';
482+
if (code.startsWith('#!')) {
483+
const shebangEndPosition = code.indexOf('\n') + 1;
484+
shebang = code.slice(0, shebangEndPosition);
485+
magicString.remove(0, shebangEndPosition).trim();
486+
}
487+
481488
const exportMode = isEsModule
482489
? 'none'
483490
: shouldWrap
@@ -561,13 +568,13 @@ function ${requireName} () {
561568

562569
magicString
563570
.trim()
564-
.prepend(leadingComment + importBlock)
571+
.prepend(shebang + leadingComment + importBlock)
565572
.append(exportBlock);
566573

567574
return {
568575
code: magicString.toString(),
569576
map: sourceMap ? magicString.generateMap() : null,
570577
syntheticNamedExports: isEsModule || usesRequireWrapper ? false : '__moduleExports',
571-
meta: { commonjs: commonjsMeta }
578+
meta: { commonjs: { ...commonjsMeta, shebang } }
572579
};
573580
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env node
2+
module.exports = 1;

packages/commonjs/test/test.js

+15
Original file line numberDiff line numberDiff line change
@@ -1291,3 +1291,18 @@ test('allows the config to be reused', async (t) => {
12911291
['bar.js']
12921292
);
12931293
});
1294+
1295+
test('keep the shebang at the top of the file content', async (t) => {
1296+
const bundle = await rollup({
1297+
input: ['fixtures/samples/shebang/main.js'],
1298+
plugins: [commonjs()]
1299+
});
1300+
1301+
const { output } = await bundle.generate({
1302+
exports: 'auto',
1303+
format: 'cjs',
1304+
chunkFileNames: '[name].js'
1305+
});
1306+
1307+
t.is(output[0].code.startsWith('#!/usr/bin/env node\n'), true);
1308+
});

0 commit comments

Comments
 (0)