mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-17 02:54:21 +08:00
refactor(@ngtools/webpack): remove forwardSlashPath utility usage from Ivy plugin
A cached path normalization helper is now used in places that still require normalization. Usage was also removed completely in locations that are not needed either because the path was later normalized or the normalization would provide no benefit.
This commit is contained in:
parent
4c46c191c7
commit
ff9e245a51
@ -11,7 +11,7 @@ import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import { NgccProcessor } from '../ngcc_processor';
|
||||
import { WebpackResourceLoader } from '../resource_loader';
|
||||
import { forwardSlashPath } from '../utils';
|
||||
import { normalizePath } from './paths';
|
||||
|
||||
export function augmentHostWithResources(
|
||||
host: ts.CompilerHost,
|
||||
@ -21,7 +21,7 @@ export function augmentHostWithResources(
|
||||
const resourceHost = host as CompilerHost;
|
||||
|
||||
resourceHost.readResource = function (fileName: string) {
|
||||
const filePath = forwardSlashPath(fileName);
|
||||
const filePath = normalizePath(fileName);
|
||||
|
||||
if (
|
||||
options.directTemplateLoading &&
|
||||
@ -41,7 +41,7 @@ export function augmentHostWithResources(
|
||||
};
|
||||
|
||||
resourceHost.resourceNameToFileName = function (resourceName: string, containingFile: string) {
|
||||
return forwardSlashPath(path.join(path.dirname(containingFile), resourceName));
|
||||
return path.join(path.dirname(containingFile), resourceName);
|
||||
};
|
||||
|
||||
resourceHost.getModifiedResourceFiles = function () {
|
||||
@ -157,7 +157,7 @@ export function augmentHostWithReplacements(
|
||||
|
||||
const normalizedReplacements: Record<string, string> = {};
|
||||
for (const [key, value] of Object.entries(replacements)) {
|
||||
normalizedReplacements[forwardSlashPath(key)] = forwardSlashPath(value);
|
||||
normalizedReplacements[normalizePath(key)] = normalizePath(value);
|
||||
}
|
||||
|
||||
const tryReplace = (resolvedModule: ts.ResolvedModule | undefined) => {
|
||||
|
42
packages/ngtools/webpack/src/ivy/paths.ts
Normal file
42
packages/ngtools/webpack/src/ivy/paths.ts
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as nodePath from 'path';
|
||||
|
||||
const normalizationCache = new Map<string, string>();
|
||||
|
||||
export function normalizePath(path: string): string {
|
||||
let result = normalizationCache.get(path);
|
||||
|
||||
if (result === undefined) {
|
||||
result = nodePath.win32.normalize(path).replace(/\\/g, nodePath.posix.sep);
|
||||
normalizationCache.set(path, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const externalizationCache = new Map<string, string>();
|
||||
|
||||
function externalizeForWindows(path: string): string {
|
||||
let result = externalizationCache.get(path);
|
||||
|
||||
if (result === undefined) {
|
||||
result = nodePath.win32.normalize(path);
|
||||
externalizationCache.set(path, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export const externalizePath = (() => {
|
||||
if (process.platform !== 'win32') {
|
||||
return (path: string) => path;
|
||||
}
|
||||
|
||||
return externalizeForWindows;
|
||||
})();
|
@ -18,7 +18,6 @@ import {
|
||||
import { NgccProcessor } from '../ngcc_processor';
|
||||
import { TypeScriptPathsPlugin } from '../paths-plugin';
|
||||
import { WebpackResourceLoader } from '../resource_loader';
|
||||
import { forwardSlashPath } from '../utils';
|
||||
import { addError, addWarning } from '../webpack-diagnostics';
|
||||
import { isWebpackFiveOrHigher, mergeResolverMainFields } from '../webpack-version';
|
||||
import { DiagnosticsReporter, createDiagnosticsReporter } from './diagnostics';
|
||||
@ -30,6 +29,7 @@ import {
|
||||
augmentHostWithSubstitutions,
|
||||
augmentProgramWithVersioning,
|
||||
} from './host';
|
||||
import { externalizePath, normalizePath } from './paths';
|
||||
import { AngularPluginSymbol, FileEmitter } from './symbol';
|
||||
import { createWebpackSystem } from './system';
|
||||
import { createAotTransformers, createJitTransformers, mergeTransformers } from './transformation';
|
||||
@ -180,7 +180,7 @@ export class AngularWebpackPlugin {
|
||||
// Create a Webpack-based TypeScript compiler host
|
||||
const system = createWebpackSystem(
|
||||
compiler.inputFileSystem,
|
||||
forwardSlashPath(compiler.context),
|
||||
normalizePath(compiler.context),
|
||||
);
|
||||
const host = ts.createIncrementalCompilerHost(compilerOptions, system);
|
||||
|
||||
@ -190,7 +190,8 @@ export class AngularWebpackPlugin {
|
||||
// Invalidate existing cache based on compilation file timestamps
|
||||
for (const [file, time] of compilation.fileTimestamps) {
|
||||
if (this.buildTimestamp < time) {
|
||||
cache.delete(forwardSlashPath(file));
|
||||
// Cache stores paths using the POSIX directory separator
|
||||
cache.delete(normalizePath(file));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -254,7 +255,7 @@ export class AngularWebpackPlugin {
|
||||
const rebuild = (filename: string) => new Promise<void>((resolve) => {
|
||||
const module = modules.find(
|
||||
({ resource }: compilation.Module & { resource?: string }) =>
|
||||
resource && forwardSlashPath(resource) === filename,
|
||||
resource && normalizePath(resource) === filename,
|
||||
);
|
||||
if (!module) {
|
||||
resolve();
|
||||
@ -279,7 +280,7 @@ export class AngularWebpackPlugin {
|
||||
.map((sourceFile) => sourceFile.fileName),
|
||||
);
|
||||
modules.forEach(({ resource }: compilation.Module & { resource?: string }) => {
|
||||
const sourceFile = resource && builder.getSourceFile(forwardSlashPath(resource));
|
||||
const sourceFile = resource && builder.getSourceFile(resource);
|
||||
if (!sourceFile) {
|
||||
return;
|
||||
}
|
||||
@ -408,8 +409,7 @@ export class AngularWebpackPlugin {
|
||||
|
||||
const getDependencies = (sourceFile: ts.SourceFile) => {
|
||||
const dependencies = [];
|
||||
for (const resourceDependency of angularCompiler.getResourceDependencies(sourceFile)) {
|
||||
const resourcePath = forwardSlashPath(resourceDependency);
|
||||
for (const resourcePath of angularCompiler.getResourceDependencies(sourceFile)) {
|
||||
dependencies.push(
|
||||
resourcePath,
|
||||
// Retrieve all dependencies of the resource (stylesheet imports, etc.)
|
||||
@ -444,8 +444,7 @@ export class AngularWebpackPlugin {
|
||||
// NOTE: This can be removed once support for the deprecated lazy route string format is removed
|
||||
for (const lazyRoute of angularCompiler.listLazyRoutes()) {
|
||||
const [routeKey] = lazyRoute.route.split('#');
|
||||
const routePath = forwardSlashPath(lazyRoute.referencedModule.filePath);
|
||||
this.lazyRouteMap[routeKey] = routePath;
|
||||
this.lazyRouteMap[routeKey] = lazyRoute.referencedModule.filePath;
|
||||
}
|
||||
|
||||
return this.createFileEmitter(
|
||||
@ -513,8 +512,7 @@ export class AngularWebpackPlugin {
|
||||
const pendingAnalysis = angularCompiler.analyzeAsync().then(() => {
|
||||
for (const lazyRoute of angularCompiler.listLazyRoutes()) {
|
||||
const [routeKey] = lazyRoute.route.split('#');
|
||||
const routePath = forwardSlashPath(lazyRoute.referencedModule.filePath);
|
||||
this.lazyRouteMap[routeKey] = routePath;
|
||||
this.lazyRouteMap[routeKey] = lazyRoute.referencedModule.filePath;
|
||||
}
|
||||
|
||||
return this.createFileEmitter(builder, transformers, () => []);
|
||||
|
@ -7,45 +7,25 @@
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
import { InputFileSystem } from 'webpack';
|
||||
import { externalizePath } from './paths';
|
||||
|
||||
function shouldNotWrite(): never {
|
||||
throw new Error('Webpack TypeScript System should not write.');
|
||||
}
|
||||
|
||||
// Webpack's CachedInputFileSystem uses the default directory separator in the paths it uses
|
||||
// for keys to its cache. If the keys do not match then the file watcher will not purge outdated
|
||||
// files and cause stale data to be used in the next rebuild. TypeScript always uses a `/` (POSIX)
|
||||
// directory separator internally which is also supported with Windows system APIs. However,
|
||||
// if file operations are performed with the non-default directory separator, the Webpack cache
|
||||
// will contain a key that will not be purged.
|
||||
function createToSystemPath(): (path: string) => string {
|
||||
if (process.platform === 'win32') {
|
||||
const cache = new Map<string, string>();
|
||||
|
||||
return (path) => {
|
||||
let value = cache.get(path);
|
||||
if (value === undefined) {
|
||||
value = path.replace(/\//g, '\\');
|
||||
cache.set(path, value);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
// POSIX-like platforms retain the existing directory separator
|
||||
return (path) => path;
|
||||
}
|
||||
|
||||
export function createWebpackSystem(input: InputFileSystem, currentDirectory: string): ts.System {
|
||||
const toSystemPath = createToSystemPath();
|
||||
|
||||
// Webpack's CachedInputFileSystem uses the default directory separator in the paths it uses
|
||||
// for keys to its cache. If the keys do not match then the file watcher will not purge outdated
|
||||
// files and cause stale data to be used in the next rebuild. TypeScript always uses a `/` (POSIX)
|
||||
// directory separator internally which is also supported with Windows system APIs. However,
|
||||
// if file operations are performed with the non-default directory separator, the Webpack cache
|
||||
// will contain a key that will not be purged. `externalizePath` ensures the paths are as expected.
|
||||
const system: ts.System = {
|
||||
...ts.sys,
|
||||
readFile(path: string) {
|
||||
let data;
|
||||
try {
|
||||
data = input.readFileSync(toSystemPath(path));
|
||||
data = input.readFileSync(externalizePath(path));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
@ -60,28 +40,28 @@ export function createWebpackSystem(input: InputFileSystem, currentDirectory: st
|
||||
},
|
||||
getFileSize(path: string) {
|
||||
try {
|
||||
return input.statSync(toSystemPath(path)).size;
|
||||
return input.statSync(externalizePath(path)).size;
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
fileExists(path: string) {
|
||||
try {
|
||||
return input.statSync(toSystemPath(path)).isFile();
|
||||
return input.statSync(externalizePath(path)).isFile();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
directoryExists(path: string) {
|
||||
try {
|
||||
return input.statSync(toSystemPath(path)).isDirectory();
|
||||
return input.statSync(externalizePath(path)).isDirectory();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
getModifiedTime(path: string) {
|
||||
try {
|
||||
return input.statSync(toSystemPath(path)).mtime;
|
||||
return input.statSync(externalizePath(path)).mtime;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
import * as path from 'path';
|
||||
import * as vm from 'vm';
|
||||
import { RawSource } from 'webpack-sources';
|
||||
import { forwardSlashPath } from './utils';
|
||||
import { normalizePath } from './ivy/paths';
|
||||
|
||||
const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
|
||||
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
|
||||
@ -44,7 +44,7 @@ export class WebpackResourceLoader {
|
||||
this.changedFiles.clear();
|
||||
for (const [file, time] of parentCompilation.fileTimestamps) {
|
||||
if (this.buildTimestamp < time) {
|
||||
this.changedFiles.add(forwardSlashPath(file));
|
||||
this.changedFiles.add(normalizePath(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,7 +159,7 @@ export class WebpackResourceLoader {
|
||||
// Save the dependencies for this resource.
|
||||
this._fileDependencies.set(filePath, new Set(childCompilation.fileDependencies));
|
||||
for (const file of childCompilation.fileDependencies) {
|
||||
const resolvedFile = forwardSlashPath(file);
|
||||
const resolvedFile = normalizePath(file);
|
||||
const entry = this._reverseDependencies.get(resolvedFile);
|
||||
if (entry) {
|
||||
entry.add(filePath);
|
||||
|
Loading…
x
Reference in New Issue
Block a user