@compiled/webpack-loader 0.6.17 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/{__tests__/fixtures/async.d.ts → __fixtures__/async-styles.d.ts} +0 -0
  3. package/dist/{__tests__/fixtures/async.js → __fixtures__/async-styles.js} +2 -2
  4. package/dist/__fixtures__/async-styles.js.map +1 -0
  5. package/dist/__fixtures__/babel.d.ts +2 -0
  6. package/dist/__fixtures__/babel.js +14 -0
  7. package/dist/__fixtures__/babel.js.map +1 -0
  8. package/dist/{__tests__/fixtures → __fixtures__}/binding-not-found.d.ts +1 -1
  9. package/dist/{__tests__/fixtures → __fixtures__}/binding-not-found.js +6 -9
  10. package/dist/__fixtures__/binding-not-found.js.map +1 -0
  11. package/dist/__fixtures__/common/colors.d.ts +7 -0
  12. package/dist/{__tests__/fixtures/imports → __fixtures__/common}/colors.js +5 -4
  13. package/dist/__fixtures__/common/colors.js.map +1 -0
  14. package/dist/__fixtures__/common/css-prop.d.ts +2 -0
  15. package/dist/__fixtures__/common/css-prop.js +9 -0
  16. package/dist/__fixtures__/common/css-prop.js.map +1 -0
  17. package/dist/__fixtures__/compiled-error.d.ts +2 -0
  18. package/dist/__fixtures__/compiled-error.js +10 -0
  19. package/dist/__fixtures__/compiled-error.js.map +1 -0
  20. package/dist/__fixtures__/important-styles.d.ts +3 -0
  21. package/dist/__fixtures__/important-styles.js +7 -0
  22. package/dist/__fixtures__/important-styles.js.map +1 -0
  23. package/dist/__fixtures__/lib/loader-alias.d.ts +1 -0
  24. package/dist/__fixtures__/lib/loader-alias.js +8 -0
  25. package/dist/__fixtures__/lib/loader-alias.js.map +1 -0
  26. package/dist/__fixtures__/lib/webpack-alias.d.ts +1 -0
  27. package/dist/__fixtures__/lib/webpack-alias.js +8 -0
  28. package/dist/__fixtures__/lib/webpack-alias.js.map +1 -0
  29. package/dist/__fixtures__/loader-alias.d.ts +2 -0
  30. package/dist/__fixtures__/loader-alias.js +12 -0
  31. package/dist/__fixtures__/loader-alias.js.map +1 -0
  32. package/dist/__fixtures__/local-styles.d.ts +2 -0
  33. package/dist/__fixtures__/local-styles.js +14 -0
  34. package/dist/__fixtures__/local-styles.js.map +1 -0
  35. package/dist/__fixtures__/no-compiled-styles.d.ts +0 -0
  36. package/dist/__fixtures__/no-compiled-styles.js +3 -0
  37. package/dist/__fixtures__/no-compiled-styles.js.map +1 -0
  38. package/dist/__fixtures__/relative-styles.d.ts +3 -0
  39. package/dist/__fixtures__/relative-styles.js +34 -0
  40. package/dist/__fixtures__/relative-styles.js.map +1 -0
  41. package/dist/__fixtures__/webpack-alias.d.ts +2 -0
  42. package/dist/__fixtures__/webpack-alias.js +12 -0
  43. package/dist/__fixtures__/webpack-alias.js.map +1 -0
  44. package/dist/compiled-loader.d.ts +4 -3
  45. package/dist/compiled-loader.js +53 -17
  46. package/dist/compiled-loader.js.map +1 -1
  47. package/dist/css-loader.d.ts +3 -3
  48. package/dist/css-loader.js +4 -1
  49. package/dist/css-loader.js.map +1 -1
  50. package/dist/extract-plugin.js +5 -5
  51. package/dist/extract-plugin.js.map +1 -1
  52. package/dist/index.d.ts +1 -0
  53. package/dist/types.d.ts +4 -58
  54. package/dist/{utils/webpack.d.ts → utils.d.ts} +1 -1
  55. package/dist/{utils/webpack.js → utils.js} +1 -1
  56. package/dist/utils.js.map +1 -0
  57. package/package.json +10 -9
  58. package/src/__fixtures__/async-styles.ts +1 -0
  59. package/src/__fixtures__/babel.tsx +11 -0
  60. package/src/{__tests__/fixtures → __fixtures__}/binding-not-found.tsx +2 -1
  61. package/src/{__tests__/fixtures/imports/colors.js → __fixtures__/common/colors.ts} +4 -3
  62. package/src/__fixtures__/common/css-prop.tsx +8 -0
  63. package/src/__fixtures__/compiled-error.tsx +7 -0
  64. package/src/__fixtures__/important-styles.tsx +6 -0
  65. package/src/__fixtures__/lib/babel-cjs.d.ts +3 -0
  66. package/src/{__tests__/fixtures/node_modules → __fixtures__/lib}/babel-cjs.js +0 -0
  67. package/src/__fixtures__/lib/babel-esm.d.ts +3 -0
  68. package/src/{__tests__/fixtures/node_modules → __fixtures__/lib}/babel-esm.js +0 -0
  69. package/src/__fixtures__/lib/loader-alias.ts +5 -0
  70. package/src/__fixtures__/lib/webpack-alias.ts +5 -0
  71. package/src/__fixtures__/loader-alias.tsx +8 -0
  72. package/src/__fixtures__/local-styles.tsx +14 -0
  73. package/src/__fixtures__/no-compiled-styles.ts +1 -0
  74. package/src/__fixtures__/relative-styles.tsx +39 -0
  75. package/src/__fixtures__/webpack-alias.tsx +8 -0
  76. package/src/__tests__/compiled-loader.test.tsx +70 -39
  77. package/src/__tests__/extract-plugin.test.tsx +82 -48
  78. package/src/__tests__/test-utils.tsx +103 -0
  79. package/src/compiled-loader.tsx +70 -34
  80. package/src/css-loader.tsx +9 -5
  81. package/src/extract-plugin.tsx +4 -3
  82. package/src/index.tsx +1 -0
  83. package/src/types.tsx +5 -60
  84. package/src/{utils/webpack.tsx → utils.tsx} +1 -1
  85. package/dist/__tests__/fixtures/async.js.map +0 -1
  86. package/dist/__tests__/fixtures/babel.d.ts +0 -1
  87. package/dist/__tests__/fixtures/babel.js +0 -14
  88. package/dist/__tests__/fixtures/babel.js.map +0 -1
  89. package/dist/__tests__/fixtures/binding-not-found.js.map +0 -1
  90. package/dist/__tests__/fixtures/important-styles.d.ts +0 -2
  91. package/dist/__tests__/fixtures/important-styles.js +0 -6
  92. package/dist/__tests__/fixtures/important-styles.js.map +0 -1
  93. package/dist/__tests__/fixtures/imports/colors.d.ts +0 -6
  94. package/dist/__tests__/fixtures/imports/colors.js.map +0 -1
  95. package/dist/__tests__/fixtures/imports/css-prop.d.ts +0 -1
  96. package/dist/__tests__/fixtures/imports/css-prop.js +0 -8
  97. package/dist/__tests__/fixtures/imports/css-prop.js.map +0 -1
  98. package/dist/__tests__/fixtures/multiple.d.ts +0 -2
  99. package/dist/__tests__/fixtures/multiple.js +0 -28
  100. package/dist/__tests__/fixtures/multiple.js.map +0 -1
  101. package/dist/__tests__/fixtures/single.d.ts +0 -2
  102. package/dist/__tests__/fixtures/single.js +0 -6
  103. package/dist/__tests__/fixtures/single.js.map +0 -1
  104. package/dist/__tests__/utils/webpack.d.ts +0 -6
  105. package/dist/__tests__/utils/webpack.js +0 -81
  106. package/dist/__tests__/utils/webpack.js.map +0 -1
  107. package/dist/utils/webpack.js.map +0 -1
  108. package/src/__tests__/fixtures/async.js +0 -1
  109. package/src/__tests__/fixtures/babel.js +0 -11
  110. package/src/__tests__/fixtures/important-styles.js +0 -5
  111. package/src/__tests__/fixtures/imports/css-prop.js +0 -4
  112. package/src/__tests__/fixtures/multiple.js +0 -28
  113. package/src/__tests__/fixtures/single.js +0 -5
  114. package/src/__tests__/utils/webpack.tsx +0 -88
@@ -1,65 +1,99 @@
1
- import { bundle } from './utils/webpack';
1
+ import { join } from 'path';
2
+
3
+ import { bundle as bundleEntry } from './test-utils';
4
+ import type { BundleOptions } from './test-utils';
2
5
 
3
6
  describe('CompiledExtractPlugin', () => {
4
7
  const assetName = 'static/compiled-css.css';
8
+ const fixturesPath = join(__dirname, '..', '__fixtures__');
9
+
10
+ const bundle = (entry: string, options: Omit<BundleOptions, 'mode'> = {}) =>
11
+ bundleEntry(entry, {
12
+ ...options,
13
+ extract: true,
14
+ mode: 'production',
15
+ });
16
+
17
+ it('throws when the plugin is not configured', async () => {
18
+ const errors = await bundle(join(fixturesPath, 'local-styles.tsx'), {
19
+ disableExtractPlugin: true,
20
+ }).catch((err) => err);
5
21
 
6
- it('should extract styles from a single file into a style sheet', async () => {
7
- const actual = await bundle(require.resolve('./fixtures/single.js'));
22
+ expect(errors).toEqual([
23
+ expect.objectContaining({
24
+ message: expect.stringContaining("You forgot to add the 'CompiledExtractPlugin' plugin"),
25
+ }),
26
+ ]);
27
+ }, 10000);
28
+
29
+ it('extracts local styles', async () => {
30
+ const actual = await bundle(join(fixturesPath, 'local-styles.tsx'));
8
31
 
9
32
  expect(actual[assetName]).toMatchInlineSnapshot(`
10
- "._1wyb1fwx{font-size:12px}
33
+ "._1wybdlk8{font-size:14px}
34
+ ._syaz13q2{color:blue}
11
35
  "
12
36
  `);
13
- });
37
+ }, 10000);
14
38
 
15
- it('should extract styles from multiple files into a style sheet', async () => {
16
- const actual = await bundle(require.resolve('./fixtures/multiple.js'));
39
+ it('extracts styles imported through a relative path', async () => {
40
+ const actual = await bundle(join(fixturesPath, 'relative-styles.tsx'));
17
41
 
42
+ // This should not contain any styles from the unused relative import ./common/css-prop, which includes
43
+ // {color:coral} or {border:2px solid coral}
18
44
  expect(actual[assetName]).toMatchInlineSnapshot(`
19
45
  "
20
46
  ._syaz5scu{color:red}
21
47
  ._syazmu8g{color:blueviolet}
22
- ._19itgh5a{border:2px solid orange}
23
- ._syazruxl{color:orange}
24
48
  ._f8pjruxl:focus{color:orange}
25
49
  ._f8pj1cnh:focus{color:purple}._30l31gy6:hover{color:yellow}
26
50
  ._30l313q2:hover{color:blue}
27
51
  "
28
52
  `);
29
- });
53
+ }, 10000);
30
54
 
31
- it('should extract styles from an async chunk', async () => {
32
- const actual = await bundle(require.resolve('./fixtures/async.js'));
55
+ it('extracts styles imported through a webpack alias', async () => {
56
+ const assets = await bundle(join(fixturesPath, 'webpack-alias.tsx'));
33
57
 
34
- // Only generate one CSS bundle
35
- expect(Object.keys(actual)).toMatchInlineSnapshot(`
36
- Array [
37
- "bundle.js",
38
- "298.bundle.js",
39
- "static/compiled-css.css",
40
- "298.bundle.js.LICENSE.txt",
41
- ]
58
+ expect(assets[assetName]).toMatchInlineSnapshot(`
59
+ "._syaz13q2{color:blue}
60
+ "
42
61
  `);
43
- // Extract the styles into said bundle
44
- expect(actual[assetName]).toMatchInlineSnapshot(`
45
- "._19itgh5a{border:2px solid orange}
46
- ._syazruxl{color:orange}
62
+ }, 10000);
63
+
64
+ it('extracts styles imported through an overridden resolve configuration', async () => {
65
+ const assets = await bundle(join(fixturesPath, 'loader-alias.tsx'), {
66
+ resolve: {
67
+ // This alias will be put into the compiled plugin options, but not the webpack resolve configuration
68
+ alias: {
69
+ 'loader-alias': join(fixturesPath, 'lib', 'loader-alias.ts'),
70
+ },
71
+ },
72
+ });
73
+
74
+ expect(assets[assetName]).toMatchInlineSnapshot(`
75
+ "._syaz1if8{color:indigo}
47
76
  "
48
77
  `);
49
- });
78
+ }, 10000);
50
79
 
51
- it('should throw when plugin is not configured', async () => {
52
- const error: Error = await bundle(require.resolve('./fixtures/single.js'), {
53
- disablePlugins: true,
54
- }).catch((err) => err);
80
+ it('extracts styles from an async chunk', async () => {
81
+ const actual = await bundle(join(fixturesPath, 'async-styles.ts'));
55
82
 
56
- expect(error[0].message).toInclude(
57
- `You forgot to add the 'CompiledExtractPlugin' plugin (i.e \`{ plugins: [new CompiledExtractPlugin()] }\`), please read https://compiledcssinjs.com/docs/css-extraction-webpack`
58
- );
59
- });
83
+ // Only generate one CSS bundle
84
+ const cssFiles = Object.keys(actual).filter((key) => key.endsWith('.css'));
85
+ expect(cssFiles).toHaveLength(1);
60
86
 
61
- it('should extract from a pre-built babel files', async () => {
62
- const actual = await bundle(require.resolve('./fixtures/babel.js'));
87
+ // Extract the styles into said bundle
88
+ expect(actual[assetName]).toMatchInlineSnapshot(`
89
+ "._19it1e35{border:2px solid coral}
90
+ ._syaz1vyr{color:coral}
91
+ "
92
+ `);
93
+ }, 10000);
94
+
95
+ it('extracts styles from a pre-built babel files', async () => {
96
+ const actual = await bundle(join(fixturesPath, 'babel.tsx'));
63
97
 
64
98
  expect(actual[assetName]).toMatchInlineSnapshot(`
65
99
  "._19pk1ul9{margin-top:30px}
@@ -72,10 +106,20 @@ describe('CompiledExtractPlugin', () => {
72
106
  ._syaz13q2{color:blue}
73
107
  "
74
108
  `);
75
- });
109
+ }, 10000);
110
+
111
+ it('extracts important styles', async () => {
112
+ const actual = await bundle(join(fixturesPath, 'important-styles.tsx'));
113
+
114
+ expect(actual[assetName]).toMatchInlineSnapshot(`
115
+ "._syaz13q2{color:blue}
116
+ ._1wybc038{font-size:12!important}
117
+ "
118
+ `);
119
+ }, 10000);
76
120
 
77
121
  it('should find bindings', async () => {
78
- const actual = await bundle(require.resolve('./fixtures/binding-not-found.tsx'));
122
+ const actual = await bundle(join(fixturesPath, 'binding-not-found.tsx'));
79
123
 
80
124
  expect(actual[assetName]).toMatchInlineSnapshot(`
81
125
  "._syaz1r31{color:currentColor}
@@ -103,15 +147,5 @@ describe('CompiledExtractPlugin', () => {
103
147
  ._4t3i1jdh{height:9rem}
104
148
  "
105
149
  `);
106
- });
107
-
108
- it('should extract important', async () => {
109
- const actual = await bundle(require.resolve('./fixtures/important-styles.js'));
110
-
111
- expect(actual[assetName]).toMatchInlineSnapshot(`
112
- "._syaz13q2{color:blue}
113
- ._1wybc038{font-size:12!important}
114
- "
115
- `);
116
- });
150
+ }, 10000);
117
151
  });
@@ -0,0 +1,103 @@
1
+ import { join } from 'path';
2
+
3
+ import { Volume, createFsFromVolume } from 'memfs';
4
+ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
5
+ import webpack from 'webpack';
6
+
7
+ import { CompiledExtractPlugin } from '../index';
8
+ import type { ResolveOptions } from '../index';
9
+
10
+ export interface BundleOptions {
11
+ extract?: boolean;
12
+ disableExtractPlugin?: boolean;
13
+ mode: 'development' | 'production';
14
+ resolve?: ResolveOptions;
15
+ }
16
+
17
+ export function bundle(
18
+ entry: string,
19
+ { extract = false, disableExtractPlugin = false, mode, resolve = {} }: BundleOptions
20
+ ): Promise<Record<string, string>> {
21
+ const outputPath = join(__dirname, 'dist');
22
+ const compiler = webpack({
23
+ entry,
24
+ mode,
25
+ module: {
26
+ rules: [
27
+ {
28
+ test: /\.[jt]sx?$/,
29
+ exclude: /node_modules/,
30
+ use: [
31
+ {
32
+ loader: 'babel-loader',
33
+ options: {
34
+ babelrc: false,
35
+ configFile: false,
36
+ presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react'],
37
+ },
38
+ },
39
+ {
40
+ loader: '@compiled/webpack-loader',
41
+ options: {
42
+ extract,
43
+ importReact: false,
44
+ resolve,
45
+ },
46
+ },
47
+ ],
48
+ },
49
+ {
50
+ test: /\.css$/i,
51
+ sideEffects: true,
52
+ use: [MiniCssExtractPlugin.loader, 'css-loader'],
53
+ },
54
+ ],
55
+ },
56
+ optimization: {
57
+ usedExports: false,
58
+ },
59
+ output: {
60
+ filename: '[name].js',
61
+ path: outputPath,
62
+ },
63
+ plugins: [
64
+ new MiniCssExtractPlugin({ filename: 'static/[name].css' }),
65
+ ...(disableExtractPlugin ? [] : [new CompiledExtractPlugin()]),
66
+ ],
67
+ resolve: {
68
+ alias: {
69
+ 'webpack-alias': join(__dirname, '..', '__fixtures__', 'lib', 'webpack-alias.ts'),
70
+ },
71
+ extensions: ['.tsx', '.ts', '.jsx', '.js'],
72
+ },
73
+ });
74
+
75
+ const fs = createFsFromVolume(new Volume());
76
+ // @ts-ignore
77
+ compiler.outputFileSystem = fs;
78
+ // @ts-ignore
79
+ compiler.intermediateFileSystem = fs;
80
+
81
+ return new Promise<Record<string, string>>((resolve, reject) => {
82
+ compiler.run((err, stats) => {
83
+ if (err) {
84
+ reject(err);
85
+ return;
86
+ }
87
+
88
+ if (stats?.hasErrors()) {
89
+ reject(stats.toJson().errors);
90
+ return;
91
+ }
92
+
93
+ const assets: Record<string, string> = {};
94
+
95
+ Object.keys(stats?.compilation.assets || {}).map((name) => {
96
+ const file = fs.readFileSync(join(outputPath, name), { encoding: 'utf-8' });
97
+ assets[name] = file as string;
98
+ });
99
+
100
+ resolve(assets);
101
+ });
102
+ });
103
+ }
@@ -1,49 +1,63 @@
1
- import path from 'path';
2
- import { transformFromAstAsync, parseAsync } from '@babel/core';
1
+ import fs from 'fs';
2
+ import { dirname, normalize } from 'path';
3
+
4
+ import { parseAsync, transformFromAstAsync } from '@babel/core';
5
+ import { createError, toBoolean } from '@compiled/utils';
6
+ import { CachedInputFileSystem, ResolverFactory } from 'enhanced-resolve';
3
7
  import { getOptions } from 'loader-utils';
4
- import { toBoolean, createError } from '@compiled/utils';
5
- import type { CompiledLoaderOptions, LoaderThis } from './types';
8
+ import type { LoaderContext } from 'webpack';
9
+
6
10
  import { pluginName } from './extract-plugin';
7
- import { toURIComponent } from './utils/webpack';
11
+ import type { CompiledLoaderOptions } from './types';
12
+ import { toURIComponent } from './utils';
8
13
 
9
14
  let hasErrored = false;
10
15
 
11
16
  /**
12
17
  * Returns user configuration.
13
18
  *
14
- * @param loader
19
+ * @param context
15
20
  * @returns
16
21
  */
17
- function getLoaderOptions(context: LoaderThis<CompiledLoaderOptions>) {
22
+ function getLoaderOptions(context: LoaderContext<CompiledLoaderOptions>) {
18
23
  const {
19
24
  bake = true,
20
25
  extract = false,
21
26
  importReact = undefined,
22
27
  nonce = undefined,
23
- }: CompiledLoaderOptions =
24
- typeof context.getOptions === 'undefined'
25
- ? // Webpack v4 flow
26
- getOptions(context)
27
- : // Webpack v5 flow
28
- context.getOptions({
29
- type: 'object',
30
- properties: {
31
- importReact: {
32
- type: 'boolean',
33
- },
34
- nonce: {
35
- type: 'string',
36
- },
37
- extract: {
38
- type: 'boolean',
39
- },
40
- bake: {
41
- type: 'boolean',
42
- },
28
+ resolve = {},
29
+ }: CompiledLoaderOptions = typeof context.getOptions === 'undefined'
30
+ ? // Webpack v4 flow
31
+ getOptions(context)
32
+ : // Webpack v5 flow
33
+ context.getOptions({
34
+ type: 'object',
35
+ properties: {
36
+ bake: {
37
+ type: 'boolean',
38
+ },
39
+ extract: {
40
+ type: 'boolean',
41
+ },
42
+ importReact: {
43
+ type: 'boolean',
43
44
  },
44
- });
45
+ nonce: {
46
+ type: 'string',
47
+ },
48
+ resolve: {
49
+ type: 'object',
50
+ },
51
+ },
52
+ });
45
53
 
46
- return { bake, extract, importReact, nonce };
54
+ return {
55
+ bake,
56
+ extract,
57
+ importReact,
58
+ nonce,
59
+ resolve,
60
+ };
47
61
  }
48
62
 
49
63
  /**
@@ -53,7 +67,7 @@ function getLoaderOptions(context: LoaderThis<CompiledLoaderOptions>) {
53
67
  * @param code
54
68
  */
55
69
  export default async function compiledLoader(
56
- this: LoaderThis<CompiledLoaderOptions>,
70
+ this: LoaderContext<CompiledLoaderOptions>,
57
71
  code: string
58
72
  ): Promise<void> {
59
73
  const callback = this.async();
@@ -66,7 +80,7 @@ export default async function compiledLoader(
66
80
  try {
67
81
  const includedFiles: string[] = [];
68
82
  const foundCSSRules: string[] = [];
69
- const options = getLoaderOptions(this);
83
+ const { resolve, ...options } = getLoaderOptions(this);
70
84
 
71
85
  // Transform to an AST using the local babel config.
72
86
  const ast = await parseAsync(code, {
@@ -75,6 +89,18 @@ export default async function compiledLoader(
75
89
  rootMode: 'upward-optional',
76
90
  });
77
91
 
92
+ // Setup the default resolver, where webpack will merge any passed in options with the default
93
+ // resolve configuration. Ideally, we use this.getResolve({ ...resolve, useSyncFileSystemCalls: true, })
94
+ // However, it does not work correctly when in development mode :/
95
+ const resolver = ResolverFactory.createResolver({
96
+ // @ts-expect-error
97
+ fileSystem: new CachedInputFileSystem(fs, 4000),
98
+ ...(this._compilation?.options.resolve ?? {}),
99
+ ...resolve,
100
+ // This makes the resolver invoke the callback synchronously
101
+ useSyncFileSystemCalls: true,
102
+ });
103
+
78
104
  // Transform using the Compiled Babel Plugin - we deliberately turn off using the local config.
79
105
  const result = await transformFromAstAsync(ast!, code, {
80
106
  babelrc: false,
@@ -88,13 +114,22 @@ export default async function compiledLoader(
88
114
  ],
89
115
  options.bake && [
90
116
  '@compiled/babel-plugin',
91
- { ...options, onIncludedFiles: (files: string[]) => includedFiles.push(...files) },
117
+ {
118
+ ...options,
119
+ onIncludedFiles: (files: string[]) => includedFiles.push(...files),
120
+ resolver: {
121
+ // The resolver needs to be synchronous, as babel plugins must be synchronous
122
+ resolveSync: (context: string, request: string) => {
123
+ return resolver.resolveSync({}, dirname(context), request);
124
+ },
125
+ },
126
+ },
92
127
  ],
93
128
  ].filter(toBoolean),
94
129
  });
95
130
 
96
131
  includedFiles.forEach((file) => {
97
- this.addDependency(path.normalize(file));
132
+ this.addDependency(normalize(file));
98
133
  });
99
134
 
100
135
  let output: string = result?.code || '';
@@ -122,9 +157,10 @@ export default async function compiledLoader(
122
157
  }
123
158
  }
124
159
 
125
- export function pitch(this: LoaderThis<CompiledLoaderOptions>): void {
160
+ export function pitch(this: LoaderContext<CompiledLoaderOptions>): void {
126
161
  const options = getLoaderOptions(this);
127
162
 
163
+ // @ts-expect-error No definitions for this[pluginName]
128
164
  if (!hasErrored && options.extract && !this[pluginName]) {
129
165
  this.emitError(
130
166
  createError('webpack-loader')(
@@ -1,10 +1,11 @@
1
1
  import { URLSearchParams } from 'url';
2
- import type { LoaderThis } from './types';
2
+
3
+ import type { LoaderContext } from 'webpack';
3
4
 
4
5
  /**
5
6
  * CSSLoader will take the style query params added by `./compiled-loader.tsx` and turn it into CSS.
6
7
  */
7
- export default function CSSLoader(this: LoaderThis): string {
8
+ export default function CSSLoader(this: LoaderContext<void>): string {
8
9
  const query = new URLSearchParams(this.resourceQuery);
9
10
  const styleRule = query.get('style');
10
11
  return styleRule || '';
@@ -13,11 +14,14 @@ export default function CSSLoader(this: LoaderThis): string {
13
14
  /**
14
15
  * Moves CSSloader to the end of the loader queue so it runs first.
15
16
  */
16
- export function pitch(this: LoaderThis): void {
17
- if (this.loaders[0].path !== __filename) {
17
+ export function pitch(this: LoaderContext<void>): void {
18
+ if (this.loaders[0].pitch !== pitch) {
19
+ // If the first loader isn't this one - skip.
18
20
  return;
19
21
  }
20
22
 
23
+ // The first loader is Compiled's css-loader - we need to shift
24
+ // it to be at the end of the loader chain so it runs first (instead of last).
21
25
  const firstLoader = this.loaders.shift();
22
- this.loaders.push(firstLoader);
26
+ this.loaders.push(firstLoader!);
23
27
  }
@@ -1,13 +1,14 @@
1
1
  import { sort } from '@compiled/css';
2
- import { toBoolean, createError } from '@compiled/utils';
3
- import type { Compiler, Compilation } from 'webpack';
2
+ import { createError, toBoolean } from '@compiled/utils';
3
+ import type { Compilation, Compiler } from 'webpack';
4
+
4
5
  import type { CompiledExtractPluginOptions } from './types';
5
6
  import {
6
7
  getAssetSourceContents,
7
8
  getNormalModuleHook,
8
9
  getOptimizeAssetsHook,
9
10
  getSources,
10
- } from './utils/webpack';
11
+ } from './utils';
11
12
 
12
13
  export const pluginName = 'CompiledExtractPlugin';
13
14
  export const styleSheetName = 'compiled-css';
package/src/index.tsx CHANGED
@@ -1,2 +1,3 @@
1
1
  export { default, pitch } from './compiled-loader';
2
2
  export { CompiledExtractPlugin } from './extract-plugin';
3
+ export type { CompiledExtractPluginOptions, CompiledLoaderOptions, ResolveOptions } from './types';
package/src/types.tsx CHANGED
@@ -1,5 +1,6 @@
1
- import type { RuleSetCondition } from 'webpack';
2
- import type { pluginName } from './extract-plugin';
1
+ import type { ResolveOptions, RuleSetCondition } from 'webpack';
2
+
3
+ export type { ResolveOptions };
3
4
 
4
5
  export interface CompiledLoaderOptions {
5
6
  /**
@@ -25,67 +26,11 @@ export interface CompiledLoaderOptions {
25
26
  * read [Security](https://compiledcssinjs.com/docs/security) for more information.
26
27
  */
27
28
  nonce?: string;
28
- }
29
-
30
- export interface LoaderThis<TOptions = unknown> {
31
- /**
32
- * Query param passed to the loader.
33
- *
34
- * ```
35
- * import '!loader-module?query=params';
36
- * ```
37
- */
38
- resourceQuery: string;
39
-
40
- /**
41
- * Absolute path of this file.
42
- */
43
- resourcePath: string;
44
-
45
- /**
46
- * Returns the passed in options from a user.
47
- * Optionally validated with a `schema` object.
48
- */
49
- getOptions?: (schema?: {
50
- type: string;
51
- properties: Required<
52
- { [P in keyof TOptions]: { type: string } | { anyOf: Array<{ type: string }> } }
53
- >;
54
- }) => TOptions;
55
-
56
- /**
57
- * Notifies webpack that this loader run included another file.
58
- * When the other file changes this file will be recompiled.
59
- */
60
- addDependency(path: string): void;
61
-
62
- /**
63
- * Marks the loader async.
64
- * Call the return value when the loader has completed.
65
- */
66
- async(): (err: any, result?: string, map?: any) => void;
67
-
68
- /**
69
- * Internal access to the current webpack compiler.
70
- */
71
- _compiler: any;
72
-
73
- /**
74
- * Internal access to the loaders for this run.
75
- */
76
- loaders: any[];
77
-
78
- /**
79
- * Emits an error during the loader run.
80
- *
81
- * @param error
82
- */
83
- emitError(error: Error): void;
84
29
 
85
30
  /**
86
- * When set confirms that the extract plugin has been configured.
31
+ * Override the default `resolve` passed into webpack, which is used to statically evaluate import declarations
87
32
  */
88
- [pluginName]?: true;
33
+ resolve?: ResolveOptions;
89
34
  }
90
35
 
91
36
  export interface CompiledExtractPluginOptions {
@@ -1,4 +1,4 @@
1
- import type { Compiler, Compilation as CompilationType, sources } from 'webpack';
1
+ import type { Compilation as CompilationType, Compiler, sources } from 'webpack';
2
2
 
3
3
  /**
4
4
  * Gets the normal module hook for webpack 4 & webpack 5.
@@ -1 +0,0 @@
1
- {"version":3,"file":"async.js","sourceRoot":"","sources":["../../../src/__tests__/fixtures/async.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,kDAAO,oBAAoB,IAAE"}
@@ -1 +0,0 @@
1
- export default function Babel(): JSX.Element;
@@ -1,14 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const babel_cjs_1 = __importDefault(require("babel-cjs"));
7
- const babel_esm_1 = __importDefault(require("babel-esm"));
8
- function Babel() {
9
- return (React.createElement(React.Fragment, null,
10
- React.createElement(babel_cjs_1.default, null),
11
- React.createElement(babel_esm_1.default, null)));
12
- }
13
- exports.default = Babel;
14
- //# sourceMappingURL=babel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"babel.js","sourceRoot":"","sources":["../../../src/__tests__/fixtures/babel.js"],"names":[],"mappings":";;;;;AAAA,0DAAiC;AACjC,0DAAiC;AAEjC,SAAwB,KAAK;IAC3B,OAAO,CACL;QACE,oBAAC,mBAAQ,OAAG;QACZ,oBAAC,mBAAQ,OAAG,CACX,CACJ,CAAC;AACJ,CAAC;AAPD,wBAOC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"binding-not-found.js","sourceRoot":"","sources":["../../../src/__tests__/fixtures/binding-not-found.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAA0B;AAC1B,2CAAyC;AAEzC,MAAM,MAAM,GAAG,MAAM,CAAC;AAEtB,MAAM,YAAY,GAAG,cAAM,CAAC,MAAM,CAGhC;YACU,MAAM;;;;;;;;;;;;MAYZ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,aAAa,CAAC;WAChF,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK;CAChC,CAAC;AAEW,QAAA,aAAa,GAAG,cAAM,CAAC,GAAG,CAAA;YAC3B,MAAM;CACjB,CAAC;AAOK,MAAM,MAAM,GAAG,CAAC,EAAwD,EAAe,EAAE;QAAzE,EAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,OAAyB,EAApB,KAAK,cAAzC,uBAA2C,CAAF;IAC9D,MAAM,KAAK,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,2BAA2B,CAAC;IAE5F,OAAO,CACL,8BAAC,YAAY,kBAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,IAAM,KAAK;QACrD,qCAAG,IAAI,EAAC,GAAG,EAAC,GAAG,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,eAE9D;QACH,QAAQ,CACI,CAChB,CAAC;AACJ,CAAC,CAAC;AAXW,QAAA,MAAM,UAWjB"}
@@ -1,2 +0,0 @@
1
- export default Component;
2
- declare function Component(): JSX.Element;
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- require("@compiled/react");
4
- const Component = () => React.createElement("div", { css: { fontSize: '12!important', color: 'blue' } });
5
- exports.default = Component;
6
- //# sourceMappingURL=important-styles.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"important-styles.js","sourceRoot":"","sources":["../../../src/__tests__/fixtures/important-styles.js"],"names":[],"mappings":";;AAAA,2BAAyB;AAEzB,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,6BAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,GAAI,CAAC;AAElF,kBAAe,SAAS,CAAC"}
@@ -1,6 +0,0 @@
1
- export const purple: "purple";
2
- export const blueviolet: "blueviolet";
3
- export const blue: "blue";
4
- export const red: "red";
5
- export const orange: "orange";
6
- export const yellow: "yellow";
@@ -1 +0,0 @@
1
- {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../../../src/__tests__/fixtures/imports/colors.js"],"names":[],"mappings":";;;AAAa,QAAA,MAAM,GAAG,QAAQ,CAAC;AAClB,QAAA,UAAU,GAAG,YAAY,CAAC;AAC1B,QAAA,IAAI,GAAG,MAAM,CAAC;AACd,QAAA,GAAG,GAAG,KAAK,CAAC;AACZ,QAAA,MAAM,GAAG,QAAQ,CAAC;AAClB,QAAA,MAAM,GAAG,QAAQ,CAAC"}
@@ -1 +0,0 @@
1
- export function Orange(): JSX.Element;
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Orange = void 0;
4
- require("@compiled/react");
5
- const colors_1 = require("./colors");
6
- const Orange = () => React.createElement("div", { css: { color: colors_1.orange, border: `2px solid ${colors_1.orange}` } });
7
- exports.Orange = Orange;
8
- //# sourceMappingURL=css-prop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"css-prop.js","sourceRoot":"","sources":["../../../../src/__tests__/fixtures/imports/css-prop.js"],"names":[],"mappings":";;;AAAA,2BAAyB;AACzB,qCAAkC;AAE3B,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,6BAAK,GAAG,EAAE,EAAE,KAAK,EAAE,eAAM,EAAE,MAAM,EAAE,aAAa,eAAM,EAAE,EAAE,GAAI,CAAC;AAA9E,QAAA,MAAM,UAAwE"}
@@ -1,2 +0,0 @@
1
- export const Blue: import("react").ComponentType<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & import("@compiled/react/dist/esm/styled").StyledProps>;
2
- export const Red: import("react").ComponentType<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & import("@compiled/react/dist/esm/styled").StyledProps>;