Skip to content

Commit bb0b1d4

Browse files
authored
fix(compiler): normalize paths on windows (#4997)
* fix(compiler): normalize paths on windows this patch ensures that paths are properly normalized by the compiler. this ensures that regardless of the platform (operating system) that a project is compiled on, paths are uniformly treated internally by stencil. this has system-wide reaching effects - from the in-memory filesystem, to configuration/output target validation, and file generation. previously, stencil's in-browser compilation support included a polyfill for the following NodeJS `path` module functions: `join`, `normalize`, `relative` & `resolve`. this polyfill did the following: - it wrapped each of the aforementioned functions in a `normalizePath` function to convert Windows-style path separators (`\\`) to Unix/POSIX-style path separators (`/`) - it overwrote the standard NodeJS `path` implementations for each of these functions. as a result, calling `join` or any of the other three methods, even when importing the method from `path` like below would result in the polyfill being called: ```ts import { join } from 'path'; // this imports the polyfilled `join` // runs the native `path.join`, then normalizes the returned path const filePath = join(part1, part2); ``` while this was 'nice' in that stencil engineers didn't need to think about which implementation of `path` functions they were using, this polyfill made some behavior of the compiler hard to understand. the polyfills were removed in #4317 (b042d8b). this led to calls to the aforementioned functions to call their original implementations, rather than the wrapped implementations: ```ts import { join } from 'path'; // imports Node's `join` // run the native `path.join`, without any normalization const filePath = join(part1, part2); ``` discrepencies arose where parts of the code would explicitly wrap a call to `join()` (or one of its ilk) around a path normalization function. this caused paths to not be uniformly normalized throughout the codebase, leading to errors. since the removal of in-browser compilation, additional pull requests to fix path-related issues on windows have landed in the codebase: - #4545 (cd58d9c) - #4932 (b97dadc) this commit builds on the previous commits by attempting to move stencil's compiler completely over to polyfilled versions of the mentioned `path` functions that are explicitly imported/called. Some of the changes found herein were created/validated using Alice's codemod branch, #4996 Co-authored-by: alicewriteswrongs <alicewriteswrongs@users.noreply.github.com> STENCIL-975 Determine Scope of Path Polyfill Bug, Fix Fixes: #4980 Fixes: #4961 Spun Off: #5036, #5032, #5029 * fix validate-dist-collection tests * fix prerendered-write-path test * fix stencil-types tests this commit removes a spy on `join.resolve` and updates the mocks to properly spy on the wrapped `@utils`' `resolve` fn * fix validate-paths tests this commit updates the tests for `validate-paths`. it replaces instances of `path.join` in assertions with stencil's own `join` function. existing instances of `path.join` have been left as-is if they pertain to user input. this allows us to exercise a user using either path separator in CI (which runs in windows and linux). the cache directory is now normalized if it is absolute. otherwise, provided cache directories in `stencil.config.ts` would never get normalized * fix validate-output-www tests this commit updates the tests for `validate-paths`. it replaces instances of `path.join` in assertions with stencil's own `join` function. existing instances of `path.join` have been left as-is if they pertain to user input. this allows us to exercise a user using either path separator in CI (which runs in windows and linux). * fix validate-output-dist tests this commit updates the tests for `validate-output`. it replaces instances of `path.join` in assertions with stencil's own `join` function. existing instances of `path.join` have been left as-is if they pertain to user input. this allows us to exercise a user using either path separator in CI (which runs in windows and linux). this commit also switches `output-target.ts#getcomponentsDtsSrcFilePath` over to use Stencil's join function to fix the tests * fix validate-output-dist-custom-element tests this commit updates the tests for `validate-output-dist-custom-element`. it replaces instances of `path.join` in assertions with stencil's own `join function. existing instances of `path.join` have been left as-is if they pertain to user input. this allows us to exercise a user using either path separator in CI (which runs in windows and linux). * fix validate-testing tests this commit updates the tests for `validate-testing`. it replaces instances of `path.join` in assertions with stencil's own `join` function. existing instances of `path.join` have been left as-is if they pertain to user input. this allows us to exercise a user using either path separator in CI (which runs in windows and linux). the screenshot connector is now normalized if it is absolute. otherwise, provided connector file path in `stencil.config.ts` would never get normalized
1 parent bd826ff commit bb0b1d4

File tree

82 files changed

+345
-275
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+345
-275
lines changed

src/compiler/app-core/app-es5-disabled.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { escapeHtml, generatePreamble } from '@utils';
2-
import { join } from 'path';
1+
import { escapeHtml, generatePreamble, join } from '@utils';
32

43
import type * as d from '../../declarations';
54

src/compiler/app-core/app-polyfills.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { join } from 'path';
1+
import { join } from '@utils';
22

33
import type * as d from '../../declarations';
44

src/compiler/build/compiler-ctx.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { noop, normalizePath } from '@utils';
2-
import { basename, dirname, extname, join } from 'path';
1+
import { join, noop, normalizePath } from '@utils';
2+
import { basename, dirname, extname } from 'path';
33

44
import type * as d from '../../declarations';
55
import { buildEvents } from '../events';

src/compiler/build/watch-build.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { isString } from '@utils';
2-
import { dirname, resolve } from 'path';
1+
import { isString, resolve } from '@utils';
2+
import { dirname } from 'path';
33
import type ts from 'typescript';
44

55
import type * as d from '../../declarations';

src/compiler/bundle/core-resolve-plugin.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { isRemoteUrl, normalizeFsPath, normalizePath } from '@utils';
2-
import { dirname, join } from 'path';
1+
import { isRemoteUrl, join, normalizeFsPath, normalizePath } from '@utils';
2+
import { dirname } from 'path';
33
import type { Plugin } from 'rollup';
44

55
import type * as d from '../../declarations';

src/compiler/bundle/dev-module.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { generatePreamble } from '@utils';
2-
import { basename, dirname, join, relative } from 'path';
1+
import { generatePreamble, join, relative } from '@utils';
2+
import { basename, dirname } from 'path';
33
import { OutputOptions, rollup } from 'rollup';
44

55
import type * as d from '../../declarations';

src/compiler/bundle/dev-node-module-resolve.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { basename, dirname, join, relative } from 'path';
1+
import { join, relative } from '@utils';
2+
import { basename, dirname } from 'path';
23
import { ResolveIdResult } from 'rollup';
34

45
import type * as d from '../../declarations';

src/compiler/bundle/ext-transforms-plugin.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { hasError, isOutputTargetDistCollection, normalizeFsPath } from '@utils';
2-
import { join, relative } from 'path';
1+
import { hasError, isOutputTargetDistCollection, join, normalizeFsPath, relative } from '@utils';
32
import type { Plugin } from 'rollup';
43

54
import type * as d from '../../declarations';

src/compiler/bundle/plugin-helper.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { buildError } from '@utils';
2-
import { relative } from 'path';
1+
import { buildError, relative } from '@utils';
32

43
import type * as d from '../../declarations';
54

src/compiler/bundle/user-index-plugin.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { join } from 'path';
1+
import { join } from '@utils';
22
import type { Plugin } from 'rollup';
33

44
import type * as d from '../../declarations';

src/compiler/cache.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { join } from 'path';
1+
import { join } from '@utils';
22

33
import type * as d from '../declarations';
44
import { InMemoryFileSystem } from './sys/in-memory-fs';

src/compiler/config/config-utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { isBoolean } from '@utils';
2-
import { isAbsolute, join } from 'path';
1+
import { isBoolean, join } from '@utils';
2+
import { isAbsolute } from 'path';
33

44
import type { ConfigFlags } from '../../cli/config-flags';
55
import type * as d from '../../declarations';

src/compiler/config/outputs/validate-custom-element.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { COPY, DIST_TYPES, isBoolean, isOutputTargetDistCustomElements } from '@utils';
2-
import { join } from 'path';
1+
import { COPY, DIST_TYPES, isBoolean, isOutputTargetDistCustomElements, join } from '@utils';
32

43
import type {
54
OutputTarget,

src/compiler/config/outputs/validate-dist.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import {
99
isBoolean,
1010
isOutputTargetDist,
1111
isString,
12+
join,
13+
resolve,
1214
} from '@utils';
13-
import { isAbsolute, join, resolve } from 'path';
15+
import { isAbsolute } from 'path';
1416

1517
import type * as d from '../../../declarations';
1618
import { getAbsolutePath } from '../config-utils';

src/compiler/config/outputs/validate-docs.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import {
88
isOutputTargetDocsReadme,
99
isOutputTargetDocsVscode,
1010
isString,
11+
join,
1112
} from '@utils';
12-
import { isAbsolute, join } from 'path';
13+
import { isAbsolute } from 'path';
1314

1415
import type * as d from '../../../declarations';
1516
import { NOTE } from '../../docs/constants';

src/compiler/config/outputs/validate-hydrate-script.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import {
55
isOutputTargetHydrate,
66
isOutputTargetWww,
77
isString,
8+
join,
89
} from '@utils';
9-
import { isAbsolute, join } from 'path';
10+
import { isAbsolute } from 'path';
1011

1112
import type * as d from '../../../declarations';
1213

src/compiler/config/outputs/validate-lazy.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { DIST_LAZY, isBoolean, isOutputTargetDistLazy } from '@utils';
2-
import { join } from 'path';
1+
import { DIST_LAZY, isBoolean, isOutputTargetDistLazy, join } from '@utils';
32

43
import type * as d from '../../../declarations';
54
import { getAbsolutePath } from '../config-utils';

src/compiler/config/outputs/validate-stats.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { isOutputTargetStats, STATS } from '@utils';
2-
import { isAbsolute, join } from 'path';
1+
import { isOutputTargetStats, join, STATS } from '@utils';
2+
import { isAbsolute } from 'path';
33

44
import type * as d from '../../../declarations';
55

src/compiler/config/outputs/validate-www.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import {
77
isOutputTargetDist,
88
isOutputTargetWww,
99
isString,
10+
join,
1011
WWW,
1112
} from '@utils';
12-
import { isAbsolute, join } from 'path';
13+
import { isAbsolute } from 'path';
1314

1415
import type * as d from '../../../declarations';
1516
import { getAbsolutePath } from '../config-utils';

src/compiler/config/test/validate-output-dist-collection.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type * as d from '@stencil/core/declarations';
22
import { mockConfig, mockLoadConfigInit } from '@stencil/core/testing';
3-
import { join, resolve } from 'path';
3+
import { join, resolve } from '@utils';
44

55
import { validateConfig } from '../validate-config';
66

src/compiler/config/test/validate-output-dist-custom-element.spec.ts

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import type * as d from '@stencil/core/declarations';
22
import { mockConfig, mockLoadConfigInit } from '@stencil/core/testing';
3-
import { COPY, DIST_CUSTOM_ELEMENTS, DIST_TYPES } from '@utils';
3+
import { COPY, DIST_CUSTOM_ELEMENTS, DIST_TYPES, join } from '@utils';
44
import path from 'path';
55

66
import { validateConfig } from '../validate-config';
77

88
describe('validate-output-dist-custom-element', () => {
99
describe('validateCustomElement', () => {
10+
// use Node's resolve() here to simulate a user using either Win/Posix separators (depending on the platform these
11+
// tests are run on)
1012
const rootDir = path.resolve('/');
11-
const defaultDistDir = path.join(rootDir, 'dist', 'components');
13+
const defaultDistDir = join(rootDir, 'dist', 'components');
1214
const distCustomElementsDir = 'my-dist-custom-elements';
1315
let userConfig: d.Config;
1416

@@ -27,7 +29,7 @@ describe('validate-output-dist-custom-element', () => {
2729
{
2830
type: DIST_TYPES,
2931
dir: defaultDistDir,
30-
typesDir: path.join(rootDir, 'dist', 'types'),
32+
typesDir: join(rootDir, 'dist', 'types'),
3133
},
3234
{
3335
type: DIST_CUSTOM_ELEMENTS,
@@ -53,7 +55,7 @@ describe('validate-output-dist-custom-element', () => {
5355
{
5456
type: DIST_TYPES,
5557
dir: defaultDistDir,
56-
typesDir: path.join(rootDir, 'dist', 'types'),
58+
typesDir: join(rootDir, 'dist', 'types'),
5759
},
5860
{
5961
type: DIST_CUSTOM_ELEMENTS,
@@ -79,7 +81,7 @@ describe('validate-output-dist-custom-element', () => {
7981
{
8082
type: DIST_TYPES,
8183
dir: defaultDistDir,
82-
typesDir: path.join(rootDir, 'dist', 'types'),
84+
typesDir: join(rootDir, 'dist', 'types'),
8385
},
8486
{
8587
type: DIST_CUSTOM_ELEMENTS,
@@ -106,7 +108,7 @@ describe('validate-output-dist-custom-element', () => {
106108
{
107109
type: DIST_CUSTOM_ELEMENTS,
108110
copy: [],
109-
dir: path.join(rootDir, distCustomElementsDir),
111+
dir: join(rootDir, distCustomElementsDir),
110112
empty: true,
111113
externalRuntime: true,
112114
generateTypeDeclarations: false,
@@ -222,7 +224,7 @@ describe('validate-output-dist-custom-element', () => {
222224
{
223225
type: DIST_TYPES,
224226
dir: defaultDistDir,
225-
typesDir: path.join(rootDir, 'dist', 'types'),
227+
typesDir: join(rootDir, 'dist', 'types'),
226228
},
227229
{
228230
type: DIST_CUSTOM_ELEMENTS,
@@ -249,7 +251,7 @@ describe('validate-output-dist-custom-element', () => {
249251
{
250252
type: DIST_TYPES,
251253
dir: defaultDistDir,
252-
typesDir: path.join(rootDir, 'dist', 'types'),
254+
typesDir: join(rootDir, 'dist', 'types'),
253255
},
254256
{
255257
type: DIST_CUSTOM_ELEMENTS,
@@ -277,7 +279,7 @@ describe('validate-output-dist-custom-element', () => {
277279
{
278280
type: DIST_TYPES,
279281
dir: defaultDistDir,
280-
typesDir: path.join(rootDir, 'dist', 'types'),
282+
typesDir: join(rootDir, 'dist', 'types'),
281283
},
282284
{
283285
type: DIST_CUSTOM_ELEMENTS,
@@ -305,13 +307,13 @@ describe('validate-output-dist-custom-element', () => {
305307
expect(config.outputTargets).toEqual([
306308
{
307309
type: DIST_TYPES,
308-
dir: path.join(rootDir, distCustomElementsDir),
309-
typesDir: path.join(rootDir, 'dist', 'types'),
310+
dir: join(rootDir, distCustomElementsDir),
311+
typesDir: join(rootDir, 'dist', 'types'),
310312
},
311313
{
312314
type: DIST_CUSTOM_ELEMENTS,
313315
copy: [],
314-
dir: path.join(rootDir, distCustomElementsDir),
316+
dir: join(rootDir, distCustomElementsDir),
315317
empty: false,
316318
externalRuntime: false,
317319
generateTypeDeclarations: true,
@@ -375,7 +377,7 @@ describe('validate-output-dist-custom-element', () => {
375377
{
376378
type: DIST_CUSTOM_ELEMENTS,
377379
copy: [copyOutputTarget, copyOutputTarget2],
378-
dir: path.join(rootDir, distCustomElementsDir),
380+
dir: join(rootDir, distCustomElementsDir),
379381
empty: false,
380382
externalRuntime: false,
381383
generateTypeDeclarations: false,

0 commit comments

Comments
 (0)