diff --git a/src/after-compile.ts b/src/after-compile.ts index 03fa8543a..4bd50a738 100644 --- a/src/after-compile.ts +++ b/src/after-compile.ts @@ -357,15 +357,21 @@ function provideSolutionErrorsToWebpack( } /** - * gather all declaration files from TypeScript and output them to webpack + * gather all declaration files from TypeScript and output them to webpack. + * JavaScript declaration files are included if `allowJs` is set. */ function provideDeclarationFilesToWebpack( filesToCheckForErrors: TSFiles, instance: TSInstance, compilation: webpack.compilation.Compilation ) { + const filePathRegex = + instance.compilerOptions.allowJs === true + ? constants.dtsTsTsxJsJsxRegex + : constants.dtsTsTsxRegex; + for (const { fileName } of filesToCheckForErrors.values()) { - if (fileName.match(constants.tsTsxRegex) === null) { + if (fileName.match(filePathRegex) === null) { continue; } diff --git a/test/comparison-tests/declarationOutputAllowJs/app.ts b/test/comparison-tests/declarationOutputAllowJs/app.ts new file mode 100644 index 000000000..77428dd19 --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/app.ts @@ -0,0 +1,9 @@ +import dep = require('./sub/dep'); + +class Test extends dep { + doSomething() { + + } +} + +export = Test; \ No newline at end of file diff --git a/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/.output/app.d.ts b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/.output/app.d.ts new file mode 100644 index 000000000..42c1b770a --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/.output/app.d.ts @@ -0,0 +1,5 @@ +import dep = require('./sub/dep'); +declare class Test extends dep { + doSomething(): void; +} +export = Test; diff --git a/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/.output/sub/dep.d.ts b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/.output/sub/dep.d.ts new file mode 100644 index 000000000..41cbbcc68 --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/.output/sub/dep.d.ts @@ -0,0 +1,6 @@ +export class Test { + /** + * @param {number} x + */ + doSomething(x: number): number; +} diff --git a/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/bundle.js b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/bundle.js new file mode 100644 index 000000000..6874bab79 --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/bundle.js @@ -0,0 +1,113 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // 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; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "./app.ts"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./app.ts": +/*!****************!*\ + !*** ./app.ts ***! + \****************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar dep = __webpack_require__(/*! ./sub/dep */ \"./sub/dep.js\");\nvar Test = /** @class */ (function (_super) {\n __extends(Test, _super);\n function Test() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n Test.prototype.doSomething = function () {\n };\n return Test;\n}(dep));\nmodule.exports = Test;\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./sub/dep.js": +/*!********************!*\ + !*** ./sub/dep.js ***! + \********************/ +/*! exports provided: Test */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Test\", function() { return Test; });\n\nclass Test {\n\t/**\n\t * @param {number} x \n\t */\n\tdoSomething(x) {\n\t\treturn x;\n\t}\n}\n\n\n//# sourceURL=webpack:///./sub/dep.js?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/output.txt b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/output.txt new file mode 100644 index 000000000..234f21f1a --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-4.1/output.txt @@ -0,0 +1,12 @@ + Asset Size Chunks Chunk Names + .output/app.d.ts 110 bytes [emitted] +.output/sub/dep.d.ts 99 bytes [emitted] + bundle.js 5.25 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 934 bytes {main} [built] [1 error] +[./sub/dep.js] 89 bytes {main} [built] + +ERROR in app.ts +./app.ts 3:19-22 +[tsl] ERROR in app.ts(3,20) + TS2507: Type 'typeof import("/declarationOutputAllowJs/sub/dep")' is not a constructor function type. \ No newline at end of file diff --git a/test/comparison-tests/declarationOutputAllowJs/expectedOutput-transpile-4.1/bundle.js b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-transpile-4.1/bundle.js new file mode 100644 index 000000000..6874bab79 --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-transpile-4.1/bundle.js @@ -0,0 +1,113 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // 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; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "./app.ts"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./app.ts": +/*!****************!*\ + !*** ./app.ts ***! + \****************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar dep = __webpack_require__(/*! ./sub/dep */ \"./sub/dep.js\");\nvar Test = /** @class */ (function (_super) {\n __extends(Test, _super);\n function Test() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n Test.prototype.doSomething = function () {\n };\n return Test;\n}(dep));\nmodule.exports = Test;\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./sub/dep.js": +/*!********************!*\ + !*** ./sub/dep.js ***! + \********************/ +/*! exports provided: Test */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Test\", function() { return Test; });\n\nclass Test {\n\t/**\n\t * @param {number} x \n\t */\n\tdoSomething(x) {\n\t\treturn x;\n\t}\n}\n\n\n//# sourceURL=webpack:///./sub/dep.js?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/declarationOutputAllowJs/expectedOutput-transpile-4.1/output.txt b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-transpile-4.1/output.txt new file mode 100644 index 000000000..456e7ade1 --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/expectedOutput-transpile-4.1/output.txt @@ -0,0 +1,5 @@ + Asset Size Chunks Chunk Names +bundle.js 5.25 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 934 bytes {main} [built] +[./sub/dep.js] 89 bytes {main} [built] \ No newline at end of file diff --git a/test/comparison-tests/declarationOutputAllowJs/sub/dep.js b/test/comparison-tests/declarationOutputAllowJs/sub/dep.js new file mode 100644 index 000000000..2c8a0dde7 --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/sub/dep.js @@ -0,0 +1,9 @@ + +export class Test { + /** + * @param {number} x + */ + doSomething(x) { + return x; + } +} diff --git a/test/comparison-tests/declarationOutputAllowJs/tsconfig.json b/test/comparison-tests/declarationOutputAllowJs/tsconfig.json new file mode 100644 index 000000000..a777685f1 --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "declaration": true, + "declarationDir": ".output", + "allowJs": true + }, + "files": [ + "./app.ts", + "./sub/dep.js" + ] +} diff --git a/test/comparison-tests/declarationOutputAllowJs/webpack.config.js b/test/comparison-tests/declarationOutputAllowJs/webpack.config.js new file mode 100644 index 000000000..2159baf3b --- /dev/null +++ b/test/comparison-tests/declarationOutputAllowJs/webpack.config.js @@ -0,0 +1,15 @@ +module.exports = { + mode: 'development', + entry: './app.ts', + output: { + filename: 'bundle.js' + }, + resolve: { + extensions: ['.ts', '.js'] + }, + module: { + rules: [ + { test: /\.ts$/, loader: 'ts-loader' } + ] + } +}