From b4edcf4b4b1691f2420c5d5afa201bedc8edd54b Mon Sep 17 00:00:00 2001 From: Amir Musaev Date: Fri, 21 Feb 2020 09:01:20 -0500 Subject: [PATCH] Support `.js` imports from typescript (#510) This resolves https://github.com/zeit/ncc/issues/508 in allowing the pattern for TypeScript code using `.js` extensions to reference other TypeScript files. This is currently recommended by the TypeScript team (https://github.com/microsoft/TypeScript/issues/16577#issuecomment-309169829) as an approach for writing TypeScript that will include the file extensions in the output files when using `tsc` manually, resulting in Node.js and browser compatibility for the output. With this PR, ncc doesn't have to break enabling this workflow for users, while remaining backwards compatible with the previous behaviour so it would be fine to release this as a minor. --- src/index.js | 9 ++++ test/unit/ts-exts/dep-dep.ts | 1 + test/unit/ts-exts/dep.ts | 2 + test/unit/ts-exts/input.ts | 3 ++ test/unit/ts-exts/output-coverage.js | 81 ++++++++++++++++++++++++++++ test/unit/ts-exts/output.js | 81 ++++++++++++++++++++++++++++ test/unit/ts-exts/tsconfig.json | 10 ++++ 7 files changed, 187 insertions(+) create mode 100644 test/unit/ts-exts/dep-dep.ts create mode 100644 test/unit/ts-exts/dep.ts create mode 100644 test/unit/ts-exts/input.ts create mode 100644 test/unit/ts-exts/output-coverage.js create mode 100644 test/unit/ts-exts/output.js create mode 100644 test/unit/ts-exts/tsconfig.json diff --git a/src/index.js b/src/index.js index 8951c14c..fd2e4c37 100644 --- a/src/index.js +++ b/src/index.js @@ -94,6 +94,15 @@ module.exports = ( if (!err) return callback(null, result); if (!err.missing || !err.missing.length) return callback(err); + // Allow .js resolutions to .tsx? from .tsx? + if (request.endsWith('.js') && context.issuer && (context.issuer.endsWith('.ts') || context.issuer.endsWith('.tsx'))) + return resolve.call(resolver, context, path, request.slice(0, -3), resolveContext, function (err, result) { + if (!err) return callback(null, result); + if (!err.missing || !err.missing.length) + return callback(err); + // make not found errors runtime errors + callback(null, __dirname + '/@@notfound.js' + '?' + (externalMap.get(request) || request)); + }); // make not found errors runtime errors callback(null, __dirname + '/@@notfound.js' + '?' + (externalMap.get(request) || request)); }); diff --git a/test/unit/ts-exts/dep-dep.ts b/test/unit/ts-exts/dep-dep.ts new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/test/unit/ts-exts/dep-dep.ts @@ -0,0 +1 @@ +export default {}; diff --git a/test/unit/ts-exts/dep.ts b/test/unit/ts-exts/dep.ts new file mode 100644 index 00000000..dde0587c --- /dev/null +++ b/test/unit/ts-exts/dep.ts @@ -0,0 +1,2 @@ +export { default } from './dep-dep.js'; + diff --git a/test/unit/ts-exts/input.ts b/test/unit/ts-exts/input.ts new file mode 100644 index 00000000..206c8296 --- /dev/null +++ b/test/unit/ts-exts/input.ts @@ -0,0 +1,3 @@ +import dep from './dep.js'; + +console.log(dep); diff --git a/test/unit/ts-exts/output-coverage.js b/test/unit/ts-exts/output-coverage.js new file mode 100644 index 00000000..a31220e5 --- /dev/null +++ b/test/unit/ts-exts/output-coverage.js @@ -0,0 +1,81 @@ +module.exports = +/******/ (function(modules, runtime) { // webpackBootstrap +/******/ "use strict"; +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ __webpack_require__.ab = __dirname + "/"; +/******/ +/******/ // the startup function +/******/ function startup() { +/******/ // Load entry module and return exports +/******/ return __webpack_require__(368); +/******/ }; +/******/ +/******/ // run startup +/******/ return startup(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 43: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +exports.__esModule = true; +var dep_dep_js_1 = __webpack_require__(119); +exports["default"] = dep_dep_js_1["default"]; + + +/***/ }), + +/***/ 119: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +exports.__esModule = true; +exports["default"] = {}; + + +/***/ }), + +/***/ 368: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +exports.__esModule = true; +var dep_js_1 = __webpack_require__(43); +console.log(dep_js_1["default"]); + + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/unit/ts-exts/output.js b/test/unit/ts-exts/output.js new file mode 100644 index 00000000..dc51ed6d --- /dev/null +++ b/test/unit/ts-exts/output.js @@ -0,0 +1,81 @@ +module.exports = +/******/ (function(modules, runtime) { // webpackBootstrap +/******/ "use strict"; +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ __webpack_require__.ab = __dirname + "/"; +/******/ +/******/ // the startup function +/******/ function startup() { +/******/ // Load entry module and return exports +/******/ return __webpack_require__(578); +/******/ }; +/******/ +/******/ // run startup +/******/ return startup(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 578: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +exports.__esModule = true; +var dep_js_1 = __webpack_require__(975); +console.log(dep_js_1["default"]); + + +/***/ }), + +/***/ 668: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +exports.__esModule = true; +exports["default"] = {}; + + +/***/ }), + +/***/ 975: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +exports.__esModule = true; +var dep_dep_js_1 = __webpack_require__(668); +exports["default"] = dep_dep_js_1["default"]; + + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/unit/ts-exts/tsconfig.json b/test/unit/ts-exts/tsconfig.json new file mode 100644 index 00000000..a44f3b75 --- /dev/null +++ b/test/unit/ts-exts/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "moduleResolution": "node", + "baseUrl": ".", + "paths": { + "@*": ["./*"] + } + } +}