Skip to content

Commit 21801fa

Browse files
fix: Reorder extension resolution to prioritise TypeScript over JSON (#1315)
When a directory contains both `test.json` and `test.ts`, an extensionless import like: ```ts import { myFunction } from './test'; ``` resolves to `test.json` instead of `test.ts`, causing all exported methods from the TypeScript file to be unresolvable during the build. Webpack resolves extensions in the order they appear in the `resolve.extensions` array. Since `.json` appears before `.ts` and `.tsx`, webpack picks the JSON file first when both exist. ### Reproduce (The test project need a `tsconfig.json` with `compilerOptions.resolveJsonModule: true`) 1. Create a directory with two files sharing the same base name: **`src/test.json`** ```json { "key": "value" } ``` **`src/test.ts`** ```ts export function greet(): string { return "hello"; } ``` 2. Import without an extension from another TypeScript file: **`src/index.ts`** ```ts import { greet } from './test'; console.log(greet()); ``` 3. Run `ncc build src/index.ts` the build fails because `./test` resolves to `test.json`, which has no `greet` export.
1 parent e7c0c70 commit 21801fa

7 files changed

Lines changed: 155 additions & 1 deletion

File tree

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const { hasTypeModule } = require('./utils/has-type-module');
1717
// support glob graceful-fs
1818
fs.gracefulify(require("fs"));
1919

20-
const SUPPORTED_EXTENSIONS = [".js", ".json", ".node", ".mjs", ".ts", ".tsx"];
20+
const SUPPORTED_EXTENSIONS = [".js", ".mjs", ".ts", ".tsx", ".json", ".node"];
2121

2222
const hashOf = name => {
2323
return crypto

test/unit/ts-json-resolve/dep.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "key": "value" }

test/unit/ts-json-resolve/dep.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function greet(): string {
2+
return "hello";
3+
}

test/unit/ts-json-resolve/input.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { greet } from "./dep";
2+
console.log(greet());
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/******/ (() => { // webpackBootstrap
2+
/******/ "use strict";
3+
/******/ var __webpack_modules__ = ({
4+
5+
/***/ 827:
6+
/***/ ((__unused_webpack_module, exports) => {
7+
8+
9+
Object.defineProperty(exports, "__esModule", ({ value: true }));
10+
exports.greet = greet;
11+
function greet() {
12+
return "hello";
13+
}
14+
15+
16+
/***/ })
17+
18+
/******/ });
19+
/************************************************************************/
20+
/******/ // The module cache
21+
/******/ var __webpack_module_cache__ = {};
22+
/******/
23+
/******/ // The require function
24+
/******/ function __nccwpck_require__(moduleId) {
25+
/******/ // Check if module is in cache
26+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
27+
/******/ if (cachedModule !== undefined) {
28+
/******/ return cachedModule.exports;
29+
/******/ }
30+
/******/ // Create a new module (and put it into the cache)
31+
/******/ var module = __webpack_module_cache__[moduleId] = {
32+
/******/ // no module.id needed
33+
/******/ // no module.loaded needed
34+
/******/ exports: {}
35+
/******/ };
36+
/******/
37+
/******/ // Execute the module function
38+
/******/ var threw = true;
39+
/******/ try {
40+
/******/ __webpack_modules__[moduleId](module, module.exports, __nccwpck_require__);
41+
/******/ threw = false;
42+
/******/ } finally {
43+
/******/ if(threw) delete __webpack_module_cache__[moduleId];
44+
/******/ }
45+
/******/
46+
/******/ // Return the exports of the module
47+
/******/ return module.exports;
48+
/******/ }
49+
/******/
50+
/************************************************************************/
51+
/******/ /* webpack/runtime/compat */
52+
/******/
53+
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
54+
/******/
55+
/************************************************************************/
56+
var __webpack_exports__ = {};
57+
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
58+
(() => {
59+
var exports = __webpack_exports__;
60+
61+
Object.defineProperty(exports, "__esModule", ({ value: true }));
62+
const dep_1 = __nccwpck_require__(827);
63+
console.log((0, dep_1.greet)());
64+
65+
})();
66+
67+
module.exports = __webpack_exports__;
68+
/******/ })()
69+
;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/******/ (() => { // webpackBootstrap
2+
/******/ "use strict";
3+
/******/ var __webpack_modules__ = ({
4+
5+
/***/ 827:
6+
/***/ ((__unused_webpack_module, exports) => {
7+
8+
9+
Object.defineProperty(exports, "__esModule", ({ value: true }));
10+
exports.greet = greet;
11+
function greet() {
12+
return "hello";
13+
}
14+
15+
16+
/***/ })
17+
18+
/******/ });
19+
/************************************************************************/
20+
/******/ // The module cache
21+
/******/ var __webpack_module_cache__ = {};
22+
/******/
23+
/******/ // The require function
24+
/******/ function __nccwpck_require__(moduleId) {
25+
/******/ // Check if module is in cache
26+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
27+
/******/ if (cachedModule !== undefined) {
28+
/******/ return cachedModule.exports;
29+
/******/ }
30+
/******/ // Create a new module (and put it into the cache)
31+
/******/ var module = __webpack_module_cache__[moduleId] = {
32+
/******/ // no module.id needed
33+
/******/ // no module.loaded needed
34+
/******/ exports: {}
35+
/******/ };
36+
/******/
37+
/******/ // Execute the module function
38+
/******/ var threw = true;
39+
/******/ try {
40+
/******/ __webpack_modules__[moduleId](module, module.exports, __nccwpck_require__);
41+
/******/ threw = false;
42+
/******/ } finally {
43+
/******/ if(threw) delete __webpack_module_cache__[moduleId];
44+
/******/ }
45+
/******/
46+
/******/ // Return the exports of the module
47+
/******/ return module.exports;
48+
/******/ }
49+
/******/
50+
/************************************************************************/
51+
/******/ /* webpack/runtime/compat */
52+
/******/
53+
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
54+
/******/
55+
/************************************************************************/
56+
var __webpack_exports__ = {};
57+
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
58+
(() => {
59+
var exports = __webpack_exports__;
60+
61+
Object.defineProperty(exports, "__esModule", ({ value: true }));
62+
const dep_1 = __nccwpck_require__(827);
63+
console.log((0, dep_1.greet)());
64+
65+
})();
66+
67+
module.exports = __webpack_exports__;
68+
/******/ })()
69+
;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"moduleResolution": "node",
5+
"baseUrl": ".",
6+
"paths": {
7+
"@*": ["./*"]
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)