New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assist: ts-loader#945 #1
Changes from all commits
ab18ea9
3650695
8217d51
948cb35
84e1072
49110ef
5b096e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,11 +18,12 @@ import { | |
TSInstance | ||
} from './interfaces'; | ||
import { | ||
appendSuffixesIfMatch, | ||
arrify, | ||
formatErrors, | ||
getAndCacheOutputJSFileName, | ||
getAndCacheProjectReference, | ||
getPossiblyRenamedFilePath, | ||
isRootFileOrExempt, | ||
validateSourceMapOncePerProject | ||
} from './utils'; | ||
|
||
|
@@ -62,35 +63,15 @@ function successLoader( | |
) { | ||
const rawFilePath = path.normalize(loaderContext.resourcePath); | ||
|
||
const filePath = | ||
options.appendTsSuffixTo.length > 0 || options.appendTsxSuffixTo.length > 0 | ||
? appendSuffixesIfMatch( | ||
{ | ||
'.ts': options.appendTsSuffixTo, | ||
'.tsx': options.appendTsxSuffixTo | ||
}, | ||
rawFilePath | ||
) | ||
: rawFilePath; | ||
const filePath = getPossiblyRenamedFilePath(rawFilePath, options); | ||
|
||
const { version: fileVersion, changedFilesList } = updateFileInCache( | ||
filePath, | ||
contents, | ||
instance | ||
instance, | ||
options | ||
); | ||
|
||
if (changedFilesList && !instance.rootFileNames.has(filePath)) { | ||
reloadRootFileNamesFromConfig(loaderContext, instance); | ||
if ( | ||
!instance.rootFileNames.has(filePath) && | ||
!options.onlyCompileBundledFiles | ||
) { | ||
throw new Error( | ||
`The file ${filePath} is not part of the project specified in tsconfig.json. Make sure it is covered by the fields 'include', 'exclude' and 'files'.` | ||
); | ||
} | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved this to come after project reference handling |
||
const referencedProject = getAndCacheProjectReference(filePath, instance); | ||
if (referencedProject !== undefined) { | ||
const [relativeProjectConfigPath, relativeFilePath] = [ | ||
|
@@ -155,6 +136,18 @@ function successLoader( | |
callback | ||
); | ||
} else { | ||
if (changedFilesList && !isRootFileOrExempt(filePath, instance)) { | ||
reloadRootFileNamesFromConfig(loaderContext, instance, options); | ||
if ( | ||
!instance.rootFileNames.has(filePath) && | ||
!options.onlyCompileBundledFiles | ||
) { | ||
throw new Error( | ||
`The file ${filePath} is not part of the project specified in tsconfig.json. Make sure it is covered by the fields 'include', 'exclude' and 'files'.` | ||
); | ||
} | ||
} | ||
|
||
const { outputText, sourceMapText } = options.transpileOnly | ||
? getTranspilationEmit(filePath, contents, instance, loaderContext) | ||
: getEmit(rawFilePath, filePath, instance, loaderContext); | ||
|
@@ -178,28 +171,23 @@ function successLoader( | |
*/ | ||
function reloadRootFileNamesFromConfig( | ||
loaderContext: webpack.loader.LoaderContext, | ||
instance: TSInstance | ||
instance: TSInstance, | ||
options: LoaderOptions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
) { | ||
const { | ||
compiler, | ||
basePath, | ||
configFile, | ||
configFilePath, | ||
colors, | ||
loaderOptions | ||
} = instance; | ||
const { compiler, basePath, configFile, configFilePath, colors } = instance; | ||
|
||
const configParseResult = getConfigParseResult( | ||
compiler, | ||
configFile, | ||
basePath, | ||
configFilePath | ||
configFilePath, | ||
options | ||
); | ||
|
||
if (configParseResult.errors.length > 0 && !loaderOptions.happyPackMode) { | ||
if (configParseResult.errors.length > 0 && !options.happyPackMode) { | ||
const errors = formatErrors( | ||
configParseResult.errors, | ||
loaderOptions, | ||
options, | ||
colors, | ||
compiler, | ||
{ file: configFilePath }, | ||
|
@@ -211,7 +199,7 @@ function reloadRootFileNamesFromConfig( | |
throw new Error(colors.red('error while parsing tsconfig.json')); | ||
} | ||
|
||
updateInstanceRootFileNames(loaderOptions, instance, configParseResult); | ||
updateInstanceRootFileNames(options, instance, configParseResult); | ||
|
||
return; | ||
} | ||
|
@@ -400,7 +388,8 @@ function makeLoaderOptions(instanceName: string, loaderOptions: LoaderOptions) { | |
function updateFileInCache( | ||
filePath: string, | ||
contents: string, | ||
instance: TSInstance | ||
instance: TSInstance, | ||
options: LoaderOptions | ||
) { | ||
let fileWatcherEventKind: typescript.FileWatcherEventKind | undefined; | ||
let changedFilesList = false; | ||
|
@@ -432,6 +421,9 @@ function updateFileInCache( | |
// | ||
if (!instance.rootFileNames.has(filePath)) { | ||
instance.version!++; | ||
if (options.onlyCompileBundledFiles) { | ||
instance.rootFileNames.add(filePath); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to add the file manually, otherwise rootFileNames will just be declarations |
||
} | ||
} | ||
|
||
if (instance.watchHost !== undefined && contents === undefined) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,8 +96,7 @@ export function makeServicesHost( | |
|
||
getProjectReferences: () => projectReferences, | ||
|
||
getScriptFileNames: () => | ||
[...files.keys()].filter(filePath => filePath.match(scriptRegex)), | ||
getScriptFileNames: () => Array.from(instance.rootFileNames), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was the change I mentioned before that fixes TypeStrong#949. Doing this exposed a couple other problems, like needing to add the file to |
||
|
||
getScriptVersion: (fileName: string) => { | ||
fileName = path.normalize(fileName); | ||
|
@@ -351,7 +350,7 @@ export function makeWatchHost( | |
return watchHost; | ||
|
||
function getRootFileNames() { | ||
return [...files.keys()].filter(filePath => filePath.match(scriptRegex)); | ||
return Array.from(instance.rootFileNames); | ||
} | ||
|
||
function readFileWithCachingText(fileName: string, encoding?: string) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,4 @@ | ||
{ | ||
"compilerOptions": { | ||
}, | ||
"files": [ | ||
"index.vue.ts" | ||
] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1 @@ | ||
{ | ||
"compilerOptions": { | ||
"include": [ | ||
"node_modules", | ||
"app.ts" | ||
] | ||
} | ||
} | ||
{} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
{ | ||
"files": [ | ||
"./src/app.ts" | ||
"./src/app.ts", | ||
"./test/app.tests.ts" | ||
], | ||
"references": [ | ||
{ "path": "./lib" } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the heart of my changes. It solves the
appendSuffix
problem by providing TypeScript an interface to the file system that actually acts on the file names that ts-loader tracks, i.e. renamed with the.ts
or.tsx
suffix appropriately. The result is thatconfigParseResult.fileNames
will include things likefoo.vue.tsx
when ts-loader is told to assumefoo.vue
is a TSX file.Au contraire mon frère, @johnnyreilly 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's clever! But could this be a bit unintuitive for the users? Some patterns would match actual files but not transformed files. For instance, patterns like
src/**/*.vue
, or justmain.vue
inside "files". Right?Of course the user can specify patterns on the transformed files. But then the
appendSuffix
is not that transparent anymore. Maybe that's not wrong, but still pretty confusing. 🤔