From d54b294238edf590a8c0d2e11a3680b56ef88ac4 Mon Sep 17 00:00:00 2001 From: iorate Date: Thu, 21 May 2020 00:06:02 +0900 Subject: [PATCH 1/5] Apply other loaders when updating changed files --- package.json | 2 + src/instances.ts | 4 +- src/watch-run.ts | 66 ++++++++-- .../comparison-tests/otherLoadersWatch/app.ts | 2 + .../expectedOutput-3.8/bundle.js | 113 ++++++++++++++++++ .../expectedOutput-3.8/output.txt | 5 + .../expectedOutput-3.8/patch0/bundle.js | 113 ++++++++++++++++++ .../expectedOutput-3.8/patch0/output.txt | 5 + .../expectedOutput-3.8/patch1/bundle.js | 113 ++++++++++++++++++ .../expectedOutput-3.8/patch1/output.txt | 5 + .../expectedOutput-transpile-3.8/bundle.js | 113 ++++++++++++++++++ .../expectedOutput-transpile-3.8/output.txt | 5 + .../patch0/bundle.js | 113 ++++++++++++++++++ .../patch0/output.txt | 5 + .../patch1/bundle.js | 113 ++++++++++++++++++ .../patch1/output.txt | 5 + .../otherLoadersWatch/message.ts | 2 + .../otherLoadersWatch/patch0/app.ts | 3 + .../otherLoadersWatch/patch1/message.ts | 3 + .../otherLoadersWatch/remove-bug-loader.js | 1 + .../otherLoadersWatch/tsconfig.json | 5 + .../otherLoadersWatch/webpack.config.js | 21 ++++ yarn.lock | 12 ++ 23 files changed, 815 insertions(+), 14 deletions(-) create mode 100644 test/comparison-tests/otherLoadersWatch/app.ts create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/bundle.js create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/output.txt create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/bundle.js create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/output.txt create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/bundle.js create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/output.txt create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/bundle.js create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/output.txt create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/bundle.js create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/output.txt create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/bundle.js create mode 100644 test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/output.txt create mode 100644 test/comparison-tests/otherLoadersWatch/message.ts create mode 100644 test/comparison-tests/otherLoadersWatch/patch0/app.ts create mode 100644 test/comparison-tests/otherLoadersWatch/patch1/message.ts create mode 100644 test/comparison-tests/otherLoadersWatch/remove-bug-loader.js create mode 100644 test/comparison-tests/otherLoadersWatch/tsconfig.json create mode 100644 test/comparison-tests/otherLoadersWatch/webpack.config.js diff --git a/package.json b/package.json index fe82cf2c6..cc84a8815 100644 --- a/package.json +++ b/package.json @@ -55,11 +55,13 @@ "dependencies": { "chalk": "^2.3.0", "enhanced-resolve": "^4.0.0", + "loader-runner": "^3.1.0", "loader-utils": "^1.0.2", "micromatch": "^4.0.0", "semver": "^6.0.0" }, "devDependencies": { + "@types/loader-runner": "^2.2.3", "@types/micromatch": "^3.1.0", "@types/node": "*", "@types/semver": "^6.0.0", diff --git a/src/instances.ts b/src/instances.ts index 195f733d0..2f83d81b6 100644 --- a/src/instances.ts +++ b/src/instances.ts @@ -283,7 +283,7 @@ export function initializeInstance( ); loader._compiler.hooks.watchRun.tapAsync( 'ts-loader', - makeWatchRun(instance) + makeWatchRun(instance, loader) ); } } else { @@ -345,7 +345,7 @@ export function initializeInstance( ); loader._compiler.hooks.watchRun.tapAsync( 'ts-loader', - makeWatchRun(instance) + makeWatchRun(instance, loader) ); } } diff --git a/src/watch-run.ts b/src/watch-run.ts index f744d4976..ee8960851 100644 --- a/src/watch-run.ts +++ b/src/watch-run.ts @@ -1,3 +1,6 @@ +import * as fs from 'fs'; +import * as loaderRunner from 'loader-runner'; +import * as path from 'path'; import * as webpack from 'webpack'; import * as constants from './constants'; @@ -8,12 +11,19 @@ import { readFile } from './utils'; /** * Make function which will manually update changed files */ -export function makeWatchRun(instance: TSInstance) { +export function makeWatchRun( + instance: TSInstance, + loader: webpack.loader.LoaderContext +) { // Called Before starting compilation after watch const lastTimes = new Map(); const startTime = 0; - return (compiler: webpack.Compiler, callback: () => void) => { + // Save the loader index. 'loader.loaderIndex' is set to '-1' after all the loaders are run. + const loaderIndex = loader.loaderIndex; + + return (compiler: webpack.Compiler, callback: (err?: Error) => void) => { + const promises = []; if (instance.loaderOptions.transpileOnly) { instance.reportTranspileErrors = true; } else { @@ -27,7 +37,7 @@ export function makeWatchRun(instance: TSInstance) { } lastTimes.set(filePath, date); - updateFile(instance, filePath); + promises.push(updateFile(instance, loader, loaderIndex, filePath)); } // On watch update add all known dts files expect the ones in node_modules @@ -37,7 +47,7 @@ export function makeWatchRun(instance: TSInstance) { filePath.match(constants.dtsDtsxOrDtsDtsxMapRegex) !== null && filePath.match(constants.nodeModules) === null ) { - updateFile(instance, filePath); + promises.push(updateFile(instance, loader, loaderIndex, filePath)); } } } @@ -45,18 +55,50 @@ export function makeWatchRun(instance: TSInstance) { // Update all the watched files from solution builder if (instance.solutionBuilderHost) { for (const filePath of instance.solutionBuilderHost.watchedFiles.keys()) { - updateFile(instance, filePath); + promises.push(updateFile(instance, loader, loaderIndex, filePath)); } } - callback(); + Promise.all(promises) + .then(() => callback()) + .catch(err => callback(err)); }; } -function updateFile(instance: TSInstance, filePath: string) { - updateFileWithText( - instance, - filePath, - nFilePath => readFile(nFilePath) || '' - ); +function updateFile( + instance: TSInstance, + loader: webpack.loader.LoaderContext, + loaderIndex: number, + filePath: string +) { + return new Promise((resolve, reject) => { + if (instance.rootFileNames.has(path.normalize(filePath))) { + loaderRunner.runLoaders( + { + resource: filePath, + loaders: loader.loaders + .slice(loaderIndex + 1) + .map(l => ({ loader: l.path, options: l.options })), + context: {}, + readResource: fs.readFile.bind(fs) + }, + (err, result) => { + if (err) { + reject(err); + } else { + const text = result.result![0]!.toString(); + updateFileWithText(instance, filePath, () => text); + resolve(); + } + } + ); + } else { + updateFileWithText( + instance, + filePath, + nFilePath => readFile(nFilePath) || '' + ); + resolve(); + } + }); } diff --git a/test/comparison-tests/otherLoadersWatch/app.ts b/test/comparison-tests/otherLoadersWatch/app.ts new file mode 100644 index 000000000..9d035d3de --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/app.ts @@ -0,0 +1,2 @@ +import { message } from './message'; +console.log(message); diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/bundle.js b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/bundle.js new file mode 100644 index 000000000..0d390f419 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/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("\nexports.__esModule = true;\nvar message_1 = __webpack_require__(/*! ./message */ \"./message.ts\");\nconsole.log(message_1.message);\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./message.ts": +/*!********************!*\ + !*** ./message.ts ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nexports.__esModule = true;\nexports.message = 'Hello, world!';\n\n\n//# sourceURL=webpack:///./message.ts?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/output.txt b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/output.txt new file mode 100644 index 000000000..77bb1379a --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/output.txt @@ -0,0 +1,5 @@ + Asset Size Chunks Chunk Names +bundle.js 4.22 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 111 bytes {main} [built] +[./message.ts] 76 bytes {main} [built] \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/bundle.js b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/bundle.js new file mode 100644 index 000000000..0d390f419 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/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("\nexports.__esModule = true;\nvar message_1 = __webpack_require__(/*! ./message */ \"./message.ts\");\nconsole.log(message_1.message);\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./message.ts": +/*!********************!*\ + !*** ./message.ts ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nexports.__esModule = true;\nexports.message = 'Hello, world!';\n\n\n//# sourceURL=webpack:///./message.ts?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/output.txt b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/output.txt new file mode 100644 index 000000000..fde3f76a7 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch0/output.txt @@ -0,0 +1,5 @@ + Asset Size Chunks Chunk Names +bundle.js 4.22 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 111 bytes {main} [built] +[./message.ts] 76 bytes {main} \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/bundle.js b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/bundle.js new file mode 100644 index 000000000..0d390f419 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/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("\nexports.__esModule = true;\nvar message_1 = __webpack_require__(/*! ./message */ \"./message.ts\");\nconsole.log(message_1.message);\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./message.ts": +/*!********************!*\ + !*** ./message.ts ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nexports.__esModule = true;\nexports.message = 'Hello, world!';\n\n\n//# sourceURL=webpack:///./message.ts?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/output.txt b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/output.txt new file mode 100644 index 000000000..77bb1379a --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-3.8/patch1/output.txt @@ -0,0 +1,5 @@ + Asset Size Chunks Chunk Names +bundle.js 4.22 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 111 bytes {main} [built] +[./message.ts] 76 bytes {main} [built] \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/bundle.js b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/bundle.js new file mode 100644 index 000000000..b341214dd --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/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("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar message_1 = __webpack_require__(/*! ./message */ \"./message.ts\");\nconsole.log(message_1.message);\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./message.ts": +/*!********************!*\ + !*** ./message.ts ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.message = 'Hello, world!';\n\n\n//# sourceURL=webpack:///./message.ts?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/output.txt b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/output.txt new file mode 100644 index 000000000..b2a367539 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/output.txt @@ -0,0 +1,5 @@ + Asset Size Chunks Chunk Names +bundle.js 4.3 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 147 bytes {main} [built] +[./message.ts] 112 bytes {main} [built] \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/bundle.js b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/bundle.js new file mode 100644 index 000000000..b341214dd --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/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("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar message_1 = __webpack_require__(/*! ./message */ \"./message.ts\");\nconsole.log(message_1.message);\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./message.ts": +/*!********************!*\ + !*** ./message.ts ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.message = 'Hello, world!';\n\n\n//# sourceURL=webpack:///./message.ts?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/output.txt b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/output.txt new file mode 100644 index 000000000..8e6e73e57 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch0/output.txt @@ -0,0 +1,5 @@ + Asset Size Chunks Chunk Names +bundle.js 4.3 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 147 bytes {main} [built] +[./message.ts] 112 bytes {main} \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/bundle.js b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/bundle.js new file mode 100644 index 000000000..b341214dd --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/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("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar message_1 = __webpack_require__(/*! ./message */ \"./message.ts\");\nconsole.log(message_1.message);\n\n\n//# sourceURL=webpack:///./app.ts?"); + +/***/ }), + +/***/ "./message.ts": +/*!********************!*\ + !*** ./message.ts ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.message = 'Hello, world!';\n\n\n//# sourceURL=webpack:///./message.ts?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/output.txt b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/output.txt new file mode 100644 index 000000000..927644781 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/expectedOutput-transpile-3.8/patch1/output.txt @@ -0,0 +1,5 @@ + Asset Size Chunks Chunk Names +bundle.js 4.3 KiB main [emitted] main +Entrypoint main = bundle.js +[./app.ts] 147 bytes {main} +[./message.ts] 112 bytes {main} [built] \ No newline at end of file diff --git a/test/comparison-tests/otherLoadersWatch/message.ts b/test/comparison-tests/otherLoadersWatch/message.ts new file mode 100644 index 000000000..7795213e6 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/message.ts @@ -0,0 +1,2 @@ +BUG +export const message = 'Hello, world!'; diff --git a/test/comparison-tests/otherLoadersWatch/patch0/app.ts b/test/comparison-tests/otherLoadersWatch/patch0/app.ts new file mode 100644 index 000000000..c87d99bad --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/patch0/app.ts @@ -0,0 +1,3 @@ +import { message } from './message'; +BUG +console.log(message); diff --git a/test/comparison-tests/otherLoadersWatch/patch1/message.ts b/test/comparison-tests/otherLoadersWatch/patch1/message.ts new file mode 100644 index 000000000..fc9a56dc5 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/patch1/message.ts @@ -0,0 +1,3 @@ +BUG +export const message = 'Hello, world!'; +BUG diff --git a/test/comparison-tests/otherLoadersWatch/remove-bug-loader.js b/test/comparison-tests/otherLoadersWatch/remove-bug-loader.js new file mode 100644 index 000000000..c9b13abb6 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/remove-bug-loader.js @@ -0,0 +1 @@ +module.exports = contents => contents.replace(/bug/gi, ''); diff --git a/test/comparison-tests/otherLoadersWatch/tsconfig.json b/test/comparison-tests/otherLoadersWatch/tsconfig.json new file mode 100644 index 000000000..b2d4c82d5 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/tsconfig.json @@ -0,0 +1,5 @@ +{ + "exclude": [ + "patch*" + ] +} diff --git a/test/comparison-tests/otherLoadersWatch/webpack.config.js b/test/comparison-tests/otherLoadersWatch/webpack.config.js new file mode 100644 index 000000000..9ce80e4a4 --- /dev/null +++ b/test/comparison-tests/otherLoadersWatch/webpack.config.js @@ -0,0 +1,21 @@ +module.exports = { + mode: 'development', + entry: './app.ts', + output: { + filename: 'bundle.js' + }, + resolve: { + extensions: ['.ts', '.js'] + }, + module: { + rules: [ + { + test: /\.ts$/, + use: [ + { loader: 'ts-loader' }, + { loader: './remove-bug-loader.js' } + ] + } + ] + } +} diff --git a/yarn.lock b/yarn.lock index 9fbd4fa66..7dd69fa94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,6 +42,13 @@ resolved "https://registry.yarnpkg.com/@types/braces/-/braces-2.3.0.tgz#d00ec0a76562b2acb6f29330be33a093e33ed25c" integrity sha512-A3MV5EsLHgShHoJ/XES/fQAnwNISKLrFuH9eNBZY5OkTQB7JPIwbRoExvRpDsNABvkMojnKqKWS8x0m2rLYi+A== +"@types/loader-runner@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@types/loader-runner/-/loader-runner-2.2.3.tgz#c094be7fa7a29ceed61e489e1d6cd50f520a1edb" + integrity sha512-A3nrXA490GpBDqzlERopp+oJjwmkLhKNwo/uopEmJVJvR57NaC4LU/SKKZZS4zhJI9jhcOgo0VByQXfPAaoUDA== + dependencies: + "@types/node" "*" + "@types/micromatch@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-3.1.0.tgz#514c8a3d24b2680a9b838eeb80e6d7d724545433" @@ -3481,6 +3488,11 @@ loader-runner@^2.3.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== +loader-runner@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-3.1.0.tgz#e9440e5875f2ad2f968489cd2c7b59a4f2847fcb" + integrity sha512-wE/bOCdTKMR2rm7Xxh+eirDOmN7Vx7hntWgiTayuFPtF8MgsFDo49SP8kkYz8IVlEBTOtR7P+XI7bE1xjo/IkA== + loader-utils@^0.2.16: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" From 0290e65f32b4a534f462f8b2768da0699ff8f36c Mon Sep 17 00:00:00 2001 From: iorate Date: Sat, 23 May 2020 16:16:47 +0900 Subject: [PATCH 2/5] Use 'loadModule' instead of 'runLoaders' --- package.json | 3 +- src/watch-run.ts | 55 +++++++++++++++++------------------ yarn.lock | 74 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 91 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index cc84a8815..f59491356 100644 --- a/package.json +++ b/package.json @@ -55,13 +55,12 @@ "dependencies": { "chalk": "^2.3.0", "enhanced-resolve": "^4.0.0", - "loader-runner": "^3.1.0", "loader-utils": "^1.0.2", "micromatch": "^4.0.0", + "raw-loader": "^4.0.1", "semver": "^6.0.0" }, "devDependencies": { - "@types/loader-runner": "^2.2.3", "@types/micromatch": "^3.1.0", "@types/node": "*", "@types/semver": "^6.0.0", diff --git a/src/watch-run.ts b/src/watch-run.ts index ee8960851..d96d011c8 100644 --- a/src/watch-run.ts +++ b/src/watch-run.ts @@ -1,5 +1,4 @@ -import * as fs from 'fs'; -import * as loaderRunner from 'loader-runner'; +import Module = require('module'); import * as path from 'path'; import * as webpack from 'webpack'; @@ -19,7 +18,7 @@ export function makeWatchRun( const lastTimes = new Map(); const startTime = 0; - // Save the loader index. 'loader.loaderIndex' is set to '-1' after all the loaders are run. + // Save the loader index. const loaderIndex = loader.loaderIndex; return (compiler: webpack.Compiler, callback: (err?: Error) => void) => { @@ -37,7 +36,7 @@ export function makeWatchRun( } lastTimes.set(filePath, date); - promises.push(updateFile(instance, loader, loaderIndex, filePath)); + promises.push(updateFile(instance, filePath, loader, loaderIndex)); } // On watch update add all known dts files expect the ones in node_modules @@ -47,7 +46,7 @@ export function makeWatchRun( filePath.match(constants.dtsDtsxOrDtsDtsxMapRegex) !== null && filePath.match(constants.nodeModules) === null ) { - promises.push(updateFile(instance, loader, loaderIndex, filePath)); + promises.push(updateFile(instance, filePath, loader, loaderIndex)); } } } @@ -55,7 +54,7 @@ export function makeWatchRun( // Update all the watched files from solution builder if (instance.solutionBuilderHost) { for (const filePath of instance.solutionBuilderHost.watchedFiles.keys()) { - promises.push(updateFile(instance, loader, loaderIndex, filePath)); + promises.push(updateFile(instance, filePath, loader, loaderIndex)); } } @@ -67,31 +66,33 @@ export function makeWatchRun( function updateFile( instance: TSInstance, + filePath: string, loader: webpack.loader.LoaderContext, - loaderIndex: number, - filePath: string + loaderIndex: number ) { return new Promise((resolve, reject) => { - if (instance.rootFileNames.has(path.normalize(filePath))) { - loaderRunner.runLoaders( - { - resource: filePath, - loaders: loader.loaders - .slice(loaderIndex + 1) - .map(l => ({ loader: l.path, options: l.options })), - context: {}, - readResource: fs.readFile.bind(fs) - }, - (err, result) => { - if (err) { - reject(err); - } else { - const text = result.result![0]!.toString(); - updateFileWithText(instance, filePath, () => text); - resolve(); - } + if ( + loaderIndex + 1 < loader.loaders.length && + instance.rootFileNames.has(path.normalize(filePath)) + ) { + let request = '!!raw-loader?esModule=false!'; + for (let i = loaderIndex + 1; i < loader.loaders.length; ++i) { + request += loader.loaders[i].request + '!'; + } + request += filePath; + loader.loadModule(request, (err, source) => { + if (err) { + reject(err); + } else { + // Extract TypeScript code wrapped in a CommonJS module by 'raw-loader'. + // https://stackoverflow.com/questions/17581830/load-node-js-module-from-string-in-memory + const m = new Module('') as any; + m._compile(source, ''); + const text = m.exports; + updateFileWithText(instance, filePath, () => text); + resolve(); } - ); + }); } else { updateFileWithText( instance, diff --git a/yarn.lock b/yarn.lock index 7dd69fa94..abfd45be6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,13 +42,6 @@ resolved "https://registry.yarnpkg.com/@types/braces/-/braces-2.3.0.tgz#d00ec0a76562b2acb6f29330be33a093e33ed25c" integrity sha512-A3MV5EsLHgShHoJ/XES/fQAnwNISKLrFuH9eNBZY5OkTQB7JPIwbRoExvRpDsNABvkMojnKqKWS8x0m2rLYi+A== -"@types/loader-runner@^2.2.3": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@types/loader-runner/-/loader-runner-2.2.3.tgz#c094be7fa7a29ceed61e489e1d6cd50f520a1edb" - integrity sha512-A3nrXA490GpBDqzlERopp+oJjwmkLhKNwo/uopEmJVJvR57NaC4LU/SKKZZS4zhJI9jhcOgo0VByQXfPAaoUDA== - dependencies: - "@types/node" "*" - "@types/micromatch@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-3.1.0.tgz#514c8a3d24b2680a9b838eeb80e6d7d724545433" @@ -282,6 +275,11 @@ ajv-keywords@^3.1.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= +ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + ajv@^6.1.0: version "6.5.4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.4.tgz#247d5274110db653706b550fcc2b797ca28cfc59" @@ -292,6 +290,16 @@ ajv@^6.1.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.12.0: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" + integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ansi-colors@3.2.3, ansi-colors@^3.0.0: version "3.2.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" @@ -2066,6 +2074,11 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + encodeurl@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2319,6 +2332,11 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -3279,6 +3297,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -3488,11 +3513,6 @@ loader-runner@^2.3.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== -loader-runner@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-3.1.0.tgz#e9440e5875f2ad2f968489cd2c7b59a4f2847fcb" - integrity sha512-wE/bOCdTKMR2rm7Xxh+eirDOmN7Vx7hntWgiTayuFPtF8MgsFDo49SP8kkYz8IVlEBTOtR7P+XI7bE1xjo/IkA== - loader-utils@^0.2.16: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" @@ -3512,6 +3532,15 @@ loader-utils@^1.0.2, loader-utils@^1.1.0: emojis-list "^2.0.0" json5 "^1.0.1" +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3795,6 +3824,11 @@ minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" @@ -4628,6 +4662,14 @@ raw-body@2.3.3: iconv-lite "0.4.23" unpipe "1.0.0" +raw-loader@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.1.tgz#14e1f726a359b68437e183d5a5b7d33a3eba6933" + integrity sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.5" + rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -4917,6 +4959,14 @@ schema-utils@^0.4.4, schema-utils@^0.4.5: ajv "^6.1.0" ajv-keywords "^3.1.0" +schema-utils@^2.6.5: + version "2.6.6" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" + integrity sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" From 887bf6d7ca2ca075f8a2933284fe6e6a39df4d44 Mon Sep 17 00:00:00 2001 From: iorate Date: Sat, 23 May 2020 17:45:02 +0900 Subject: [PATCH 3/5] add a stringify loader --- package.json | 1 - src/stringify-loader.ts | 1 + src/watch-run.ts | 9 ++---- yarn.lock | 62 ----------------------------------------- 4 files changed, 3 insertions(+), 70 deletions(-) create mode 100644 src/stringify-loader.ts diff --git a/package.json b/package.json index f59491356..fe82cf2c6 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "enhanced-resolve": "^4.0.0", "loader-utils": "^1.0.2", "micromatch": "^4.0.0", - "raw-loader": "^4.0.1", "semver": "^6.0.0" }, "devDependencies": { diff --git a/src/stringify-loader.ts b/src/stringify-loader.ts new file mode 100644 index 000000000..5fc3e8892 --- /dev/null +++ b/src/stringify-loader.ts @@ -0,0 +1 @@ +module.exports = (source: string) => JSON.stringify(source); diff --git a/src/watch-run.ts b/src/watch-run.ts index d96d011c8..41bf6db0e 100644 --- a/src/watch-run.ts +++ b/src/watch-run.ts @@ -1,4 +1,3 @@ -import Module = require('module'); import * as path from 'path'; import * as webpack from 'webpack'; @@ -75,7 +74,7 @@ function updateFile( loaderIndex + 1 < loader.loaders.length && instance.rootFileNames.has(path.normalize(filePath)) ) { - let request = '!!raw-loader?esModule=false!'; + let request = `!!${path.resolve(__dirname, 'stringify-loader.js')}!`; for (let i = loaderIndex + 1; i < loader.loaders.length; ++i) { request += loader.loaders[i].request + '!'; } @@ -84,11 +83,7 @@ function updateFile( if (err) { reject(err); } else { - // Extract TypeScript code wrapped in a CommonJS module by 'raw-loader'. - // https://stackoverflow.com/questions/17581830/load-node-js-module-from-string-in-memory - const m = new Module('') as any; - m._compile(source, ''); - const text = m.exports; + const text = JSON.parse(source); updateFileWithText(instance, filePath, () => text); resolve(); } diff --git a/yarn.lock b/yarn.lock index abfd45be6..9fbd4fa66 100644 --- a/yarn.lock +++ b/yarn.lock @@ -275,11 +275,6 @@ ajv-keywords@^3.1.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= -ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== - ajv@^6.1.0: version "6.5.4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.4.tgz#247d5274110db653706b550fcc2b797ca28cfc59" @@ -290,16 +285,6 @@ ajv@^6.1.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^6.12.0: - version "6.12.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" - integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - ansi-colors@3.2.3, ansi-colors@^3.0.0: version "3.2.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" @@ -2074,11 +2059,6 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - encodeurl@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2332,11 +2312,6 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== - fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -3297,13 +3272,6 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -3532,15 +3500,6 @@ loader-utils@^1.0.2, loader-utils@^1.1.0: emojis-list "^2.0.0" json5 "^1.0.1" -loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3824,11 +3783,6 @@ minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" @@ -4662,14 +4616,6 @@ raw-body@2.3.3: iconv-lite "0.4.23" unpipe "1.0.0" -raw-loader@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.1.tgz#14e1f726a359b68437e183d5a5b7d33a3eba6933" - integrity sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A== - dependencies: - loader-utils "^2.0.0" - schema-utils "^2.6.5" - rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -4959,14 +4905,6 @@ schema-utils@^0.4.4, schema-utils@^0.4.5: ajv "^6.1.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.5: - version "2.6.6" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" - integrity sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA== - dependencies: - ajv "^6.12.0" - ajv-keywords "^3.4.1" - semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" From 2616d69d59f7163214188f6b1646e7eb11145c9f Mon Sep 17 00:00:00 2001 From: iorate Date: Sat, 23 May 2020 21:13:39 +0900 Subject: [PATCH 4/5] Add a comment to updateFile --- src/watch-run.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/watch-run.ts b/src/watch-run.ts index 41bf6db0e..a82899d1a 100644 --- a/src/watch-run.ts +++ b/src/watch-run.ts @@ -70,6 +70,10 @@ function updateFile( loaderIndex: number ) { return new Promise((resolve, reject) => { + // When other loaders are specified after ts-loader + // (e.g. `{ test: /\.ts$/, use: ['ts-loader', 'other-loader'] }`), + // manually apply them to TypeScript files. + // Otherwise, files not 'preprocessed' by them may cause complication errors (#1111). if ( loaderIndex + 1 < loader.loaders.length && instance.rootFileNames.has(path.normalize(filePath)) From eea2a9b50203f219294a7929deabfb24af81f1c7 Mon Sep 17 00:00:00 2001 From: iorate Date: Sun, 24 May 2020 15:17:06 +0900 Subject: [PATCH 5/5] v7.0.5 --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96225a57c..2ebeff967 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## v7.0.5 +* [Apply other loaders when updating files in watch mode](https://github.com/TypeStrong/ts-loader/pull/1115) - thanks @iorate + ## v7.0.4 * [Ensure a separate webpack instance is created for different loader options](https://github.com/TypeStrong/ts-loader/pull/1104) - thanks @appzuka diff --git a/package.json b/package.json index fe82cf2c6..38cab0f88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ts-loader", - "version": "7.0.4", + "version": "7.0.5", "description": "TypeScript loader for webpack", "main": "index.js", "types": "dist",