Skip to content

Commit 809cc38

Browse files
authoredOct 12, 2023
Support resolver module path (#1525)
1 parent c69d3a1 commit 809cc38

31 files changed

+285
-92
lines changed
 

‎.changeset/chilled-apes-lay.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/parcel-transformer-test-custom-resolver-app': minor
3+
---
4+
5+
Add resolver test application

‎.changeset/chilly-pans-relax.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/parcel-transformer': minor
3+
---
4+
5+
Add resolver configuration option

‎.changeset/strong-boats-worry.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/parcel-transformer-test-custom-resolve-app': patch
3+
---
4+
5+
Rename package to resolve over resolver

‎.changeset/violet-turtles-doubt.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/babel-plugin': minor
3+
---
4+
5+
Update resolver to support module paths

‎.changeset/wild-cups-flash.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled-private/resolver': minor
3+
---
4+
5+
Add resolver fixture
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"importReact": false,
3+
"extract": false,
4+
"optimizeCss": false,
5+
"resolve": {
6+
"alias": {
7+
"~": "../"
8+
}
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "@parcel/config-default",
3+
"transformers": {
4+
"*.{js,jsx}": ["@compiled/parcel-transformer", "..."]
5+
}
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# @compiled/parcel-transformer-test-custom-resolve-app
2+
3+
## 0.1.3
4+
5+
### Patch Changes
6+
7+
- Updated dependencies [b6f3e41e]
8+
- @compiled/react@0.15.0
9+
10+
## 0.1.2
11+
12+
### Patch Changes
13+
14+
- Updated dependencies [4a2174c5]
15+
- Updated dependencies [c5377cdb]
16+
- @compiled/react@0.14.0
17+
18+
## 0.1.1
19+
20+
### Patch Changes
21+
22+
- Updated dependencies [c4e6b7c0]
23+
- Updated dependencies [c4e6b7c0]
24+
- @compiled/react@0.13.0
25+
26+
## 0.1.0
27+
28+
### Minor Changes
29+
30+
- a41e41e6: Update monorepo node version to v18, and drop support for node v12
31+
32+
### Patch Changes
33+
34+
- Updated dependencies [a41e41e6]
35+
- Updated dependencies [f9c957ef]
36+
- @compiled/react@0.12.0
37+
38+
## 0.0.2
39+
40+
### Patch Changes
41+
42+
- 100f5d5e: Pass a custom resolver from parcel-transformer to babel plugin
43+
- Updated dependencies [13b71dfb]
44+
- @compiled/react@0.11.1
45+
46+
## 0.0.1

‎fixtures/parcel-transformer-test-custom-resolve-app/package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "@compiled/parcel-transformer-test-custom-resolve-app",
3+
"version": "0.1.3",
4+
"private": true,
5+
"dependencies": {
6+
"@compiled/react": "^0.15.0",
7+
"react": "^17.0.2",
8+
"react-dom": "^17.0.2"
9+
},
10+
"devDependencies": {
11+
"@compiled/parcel-transformer": "*",
12+
"@parcel/config-default": "^2.8.3"
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title></title>
6+
</head>
7+
<body>
8+
<div id="root"></div>
9+
<script type="module" src="./index.jsx"></script>
10+
</body>
11+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import '@compiled/react';
2+
import { color } from '~/src/foo.js';
3+
4+
const App = () => (
5+
<>
6+
<div css={{ color }}>CSS prop</div>
7+
</>
8+
);

‎fixtures/parcel-transformer-test-custom-resolver-app/.compiledcssrc

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,5 @@
22
"importReact": false,
33
"extract": false,
44
"optimizeCss": false,
5-
"resolve": {
6-
"alias": {
7-
"~": "../"
8-
}
9-
}
5+
"resolver": "@compiled-private/resolver"
106
}
Original file line numberDiff line numberDiff line change
@@ -1,46 +1 @@
11
# @compiled/parcel-transformer-test-custom-resolver-app
2-
3-
## 0.1.3
4-
5-
### Patch Changes
6-
7-
- Updated dependencies [b6f3e41e]
8-
- @compiled/react@0.15.0
9-
10-
## 0.1.2
11-
12-
### Patch Changes
13-
14-
- Updated dependencies [4a2174c5]
15-
- Updated dependencies [c5377cdb]
16-
- @compiled/react@0.14.0
17-
18-
## 0.1.1
19-
20-
### Patch Changes
21-
22-
- Updated dependencies [c4e6b7c0]
23-
- Updated dependencies [c4e6b7c0]
24-
- @compiled/react@0.13.0
25-
26-
## 0.1.0
27-
28-
### Minor Changes
29-
30-
- a41e41e6: Update monorepo node version to v18, and drop support for node v12
31-
32-
### Patch Changes
33-
34-
- Updated dependencies [a41e41e6]
35-
- Updated dependencies [f9c957ef]
36-
- @compiled/react@0.12.0
37-
38-
## 0.0.2
39-
40-
### Patch Changes
41-
42-
- 100f5d5e: Pass a custom resolver from parcel-transformer to babel plugin
43-
- Updated dependencies [13b71dfb]
44-
- @compiled/react@0.11.1
45-
46-
## 0.0.1

‎fixtures/parcel-transformer-test-custom-resolver-app/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@compiled/parcel-transformer-test-custom-resolver-app",
3-
"version": "0.1.3",
3+
"version": "0.0.0",
44
"private": true,
55
"dependencies": {
66
"@compiled/react": "^0.15.0",
@@ -10,5 +10,8 @@
1010
"devDependencies": {
1111
"@compiled/parcel-transformer": "*",
1212
"@parcel/config-default": "^2.8.3"
13+
},
14+
"alias": {
15+
"test": "../resolver/main.js"
1316
}
1417
}

‎fixtures/parcel-transformer-test-custom-resolver-app/src/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
</head>
77
<body>
88
<div id="root"></div>
9-
<script type="module" src="./index.jsx"></script>
9+
<script type="module" src="index.jsx"></script>
1010
</body>
1111
</html>
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import '@compiled/react';
2-
import { color } from '~/src/foo.js';
1+
import { css } from '@compiled/react';
2+
import { primary } from 'test';
33

4-
const App = () => (
5-
<>
6-
<div css={{ color }}>CSS prop</div>
7-
</>
8-
);
4+
const App = () => <div css={css({ color: primary })} />;

‎fixtures/resolver/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# @compiled-private/resolver

‎fixtures/resolver/index.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const { join } = require('path');
2+
3+
module.exports = {
4+
resolveSync(_, request) {
5+
if (request === 'test') {
6+
return join(__dirname, 'main.js');
7+
}
8+
9+
throw new Error('Unreachable code');
10+
},
11+
};

‎fixtures/resolver/main.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const primary = 'red';

‎fixtures/resolver/package.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "@compiled-private/resolver",
3+
"version": "0.0.0",
4+
"private": true,
5+
"main": "index.js"
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const { join } = require('path');
2+
3+
module.exports = {
4+
resolveSync(_, request) {
5+
if (request === 'test') {
6+
return join(__dirname, 'mixins', 'simple.js');
7+
}
8+
9+
throw new Error('Unreachable code');
10+
},
11+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { join } from 'path';
2+
3+
import { transform as transformCode } from '../test-utils';
4+
import type { PluginOptions } from '../types';
5+
6+
describe('resolver', () => {
7+
describe('resolves imports', () => {
8+
const fixturesRoot = join(__dirname, '..', '__fixtures__');
9+
const transform = (resolver: PluginOptions['resolver']) => {
10+
return transformCode(
11+
`
12+
import { css } from '@compiled/react';
13+
import { primary } from 'test';
14+
15+
<div css={css({ color: primary })} />
16+
`,
17+
{
18+
filename: join(__dirname, 'test.js'),
19+
resolver,
20+
}
21+
);
22+
};
23+
24+
it('using an object', () => {
25+
const actual = transform({
26+
resolveSync(_, request) {
27+
if (request === 'test') {
28+
return join(fixturesRoot, 'mixins', 'simple.js');
29+
}
30+
31+
throw new Error('Unreachable code');
32+
},
33+
});
34+
35+
expect(actual).toInclude('color:red');
36+
});
37+
38+
it('using a file path', () => {
39+
const actual = transform(join(fixturesRoot, 'resolver.js'));
40+
41+
expect(actual).toInclude('color:red');
42+
});
43+
44+
it('using a package name', () => {
45+
expect(transform('@compiled-private/resolver')).toInclude('color:red');
46+
});
47+
});
48+
});

‎packages/babel-plugin/src/babel-plugin.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default declare<State>((api) => {
3939
return {
4040
name: packageJson.name,
4141
inherits: jsxSyntax,
42-
pre() {
42+
pre(state) {
4343
this.sheets = {};
4444
this.cssMap = {};
4545
let cache: Cache;
@@ -57,6 +57,14 @@ export default declare<State>((api) => {
5757
this.includedFiles = [];
5858
this.pathsToCleanup = [];
5959
this.pragma = {};
60+
61+
if (typeof this.opts.resolver === 'object') {
62+
this.resolver = this.opts.resolver;
63+
} else if (typeof this.opts.resolver === 'string') {
64+
this.resolver = require(require.resolve(this.opts.resolver, {
65+
paths: [state.opts.root ?? this.cwd],
66+
}));
67+
}
6068
},
6169
visitor: {
6270
Program: {

‎packages/babel-plugin/src/types.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ export interface PluginOptions {
4545
optimizeCss?: boolean;
4646

4747
/**
48-
* A custom resolver used to statically evaluate import declarations
48+
* A custom resolver used to statically evaluate import declarations, specified as either an object or module path
4949
*/
50-
resolver?: Resolver;
50+
resolver?: string | Resolver;
5151

5252
/**
5353
* List of file extensions to traverse as code
@@ -147,6 +147,11 @@ export interface State extends PluginPass {
147147
* Holds a record of currently evaluated CSS Map and its sheets in the module.
148148
*/
149149
cssMap: Record<string, string[]>;
150+
151+
/**
152+
* A custom resolver used to statically evaluate import declarations
153+
*/
154+
resolver?: Resolver;
150155
}
151156

152157
interface CommonMetadata {

‎packages/babel-plugin/src/utils/resolve-binding.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ const getDestructuredObjectPatternKey = (node: t.ObjectPattern, referenceName: s
176176
};
177177

178178
const resolveRequest = (request: string, extensions: string[], meta: Metadata) => {
179-
const { filename, opts } = meta.state;
180-
const { resolver } = opts;
179+
const { filename, resolver } = meta.state;
181180
if (!filename) {
182181
throw new Error('Unable to resolve request due to a missing filename, this is probably a bug!');
183182
}

‎packages/parcel-transformer/src/__tests__/transformer.parceltest.ts

+26-9
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ import { format } from 'prettier';
66

77
const rootPath = join(__dirname, '..', '..', '..', '..');
88
const fixtureRoot = join(rootPath, 'fixtures/parcel-transformer-test-app');
9-
const extractionFixtureRoot = join(rootPath, 'fixtures/parcel-transformer-test-extract-app');
10-
const compressingClassNameFixtureRoot = join(
11-
rootPath,
12-
'fixtures/parcel-transformer-test-compress-class-name-app'
13-
);
14-
const customResolverFixtureRoot = join(
15-
rootPath,
16-
'fixtures/parcel-transformer-test-custom-resolver-app'
17-
);
189
const babelComponentFixture = join(rootPath, 'fixtures/babel-component');
1910

2011
const workerFarm = createWorkerFarm();
@@ -79,7 +70,28 @@ it('transforms assets with babel plugin', async () => {
7970
`);
8071
}, 50000);
8172

73+
it('transforms assets with custom resolve and statically evaluates imports', async () => {
74+
const customResolveFixtureRoot = join(
75+
rootPath,
76+
'fixtures/parcel-transformer-test-custom-resolve-app'
77+
);
78+
const parcel = getParcelInstance(customResolveFixtureRoot);
79+
const { changedAssets } = await parcel.run();
80+
81+
const asset = Array.from(changedAssets.values()).find(
82+
(asset) => asset.filePath === join(customResolveFixtureRoot, 'src/index.jsx')
83+
);
84+
85+
const code = await asset?.getCode();
86+
87+
expect(code).toInclude('color:red');
88+
}, 50000);
89+
8290
it('transforms assets with custom resolver and statically evaluates imports', async () => {
91+
const customResolverFixtureRoot = join(
92+
rootPath,
93+
'fixtures/parcel-transformer-test-custom-resolver-app'
94+
);
8395
const parcel = getParcelInstance(customResolverFixtureRoot);
8496
const { changedAssets } = await parcel.run();
8597

@@ -93,6 +105,7 @@ it('transforms assets with custom resolver and statically evaluates imports', as
93105
}, 50000);
94106

95107
it('transforms assets with compiled and extraction babel plugins', async () => {
108+
const extractionFixtureRoot = join(rootPath, 'fixtures/parcel-transformer-test-extract-app');
96109
const parcel = getParcelInstance(extractionFixtureRoot);
97110
const { changedAssets, bundleGraph } = await parcel.run();
98111
const assets = Array.from(changedAssets.values());
@@ -216,6 +229,10 @@ it('transforms assets with compiled and extraction babel plugins', async () => {
216229
}, 50000);
217230

218231
it('transforms assets with class name compression enabled', async () => {
232+
const compressingClassNameFixtureRoot = join(
233+
rootPath,
234+
'fixtures/parcel-transformer-test-compress-class-name-app'
235+
);
219236
const parcel = getParcelInstance(compressingClassNameFixtureRoot);
220237
const { changedAssets, bundleGraph } = await parcel.run();
221238

‎packages/parcel-transformer/src/index.ts

+2-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import fs from 'fs';
21
import { join, dirname, isAbsolute } from 'path';
32

43
import { parseAsync, transformFromAstAsync } from '@babel/core';
@@ -11,9 +10,9 @@ import type {
1110
import { toBoolean } from '@compiled/utils';
1211
import { Transformer } from '@parcel/plugin';
1312
import SourceMap from '@parcel/source-map';
14-
import { CachedInputFileSystem, ResolverFactory } from 'enhanced-resolve';
1513

1614
import type { ParcelTransformerOpts } from './types';
15+
import { createDefaultResolver } from './utils';
1716

1817
const configFiles = [
1918
'.compiledcssrc',
@@ -146,16 +145,6 @@ export default new Transformer<ParcelTransformerOpts>({
146145
const includedFiles: string[] = [];
147146
const code = asset.isASTDirty() ? undefined : await asset.getCode();
148147

149-
const resolver = ResolverFactory.createResolver({
150-
fileSystem: new CachedInputFileSystem(fs, 4000),
151-
...(config.extensions && {
152-
extensions: config.extensions,
153-
}),
154-
...(config.resolve ?? {}),
155-
// This makes the resolver invoke the callback synchronously
156-
useSyncFileSystemCalls: true,
157-
});
158-
159148
const result = await transformFromAstAsync(ast.program, code, {
160149
code: true,
161150
ast: false,
@@ -174,12 +163,7 @@ export default new Transformer<ParcelTransformerOpts>({
174163
...config,
175164
classNameCompressionMap: config.extract && config.classNameCompressionMap,
176165
onIncludedFiles: (files: string[]) => includedFiles.push(...files),
177-
resolver: {
178-
// The resolver needs to be synchronous, as babel plugins must be synchronous
179-
resolveSync: (context: string, request: string) => {
180-
return resolver.resolveSync({}, dirname(context), request);
181-
},
182-
},
166+
resolver: config.resolver ? config.resolver : createDefaultResolver(config),
183167
cache: false,
184168
} as BabelPluginOptions,
185169
],

‎packages/parcel-transformer/src/types.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ export interface ParcelTransformerOpts extends BabelPluginOpts {
3030
optimizeCss?: boolean;
3131

3232
/**
33-
* Override the default `resolve` used by @compiled/babel-plugin, which is used to statically evaluate import declarations
33+
* @deprecated Override the default `resolve` used by @compiled/babel-plugin, which is used to statically evaluate import declarations
3434
*/
3535
resolve?: ResolveOptions;
3636

37+
/**
38+
* Override the default @compiled/babel-plugin resolver, by providing a module path that exports a custom resolver
39+
*/
40+
resolver?: string;
41+
3742
/**
3843
* Add the component name as class name to DOM in non-production environment if styled is used
3944
*
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import fs from 'fs';
2+
import { dirname } from 'path';
3+
4+
import type { Resolver } from '@compiled/babel-plugin';
5+
import { CachedInputFileSystem, ResolverFactory } from 'enhanced-resolve';
6+
7+
import type { ParcelTransformerOpts } from './types';
8+
9+
export function createDefaultResolver(config: ParcelTransformerOpts): Resolver {
10+
const resolver = ResolverFactory.createResolver({
11+
fileSystem: new CachedInputFileSystem(fs, 4000),
12+
...(config.extensions && {
13+
extensions: config.extensions,
14+
}),
15+
...(config.resolve ?? {}),
16+
// This makes the resolver invoke the callback synchronously
17+
useSyncFileSystemCalls: true,
18+
});
19+
20+
return {
21+
// The resolver needs to be synchronous, as babel plugins must be synchronous
22+
resolveSync(context: string, request: string) {
23+
return resolver.resolveSync({}, dirname(context), request) as string;
24+
},
25+
};
26+
}

0 commit comments

Comments
 (0)
Please sign in to comment.