stylex-webpack 0.1.1-beta.2 → 0.1.1-beta.4
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.
- package/dist/index.d.ts +12 -11
- package/dist/index.js +37 -25
- package/dist/next.d.ts +4 -8
- package/dist/next.js +8 -4
- package/dist/stylex-loader.js +18 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import webpack from 'webpack';
|
|
2
2
|
import { Options, Rule } from '@stylexjs/babel-plugin';
|
|
3
3
|
|
|
4
|
+
interface StyleXLoaderOptions {
|
|
5
|
+
stylexImports: string[];
|
|
6
|
+
stylexOption: Partial<Options>;
|
|
7
|
+
nextjsMode: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
interface StyleXPluginOption {
|
|
5
11
|
stylexOption?: Partial<Options>;
|
|
6
|
-
/**
|
|
7
|
-
* Specify where to inject the StyleX generated CSS
|
|
8
|
-
*
|
|
9
|
-
* @default (filename) => filename.endsWith('stylex.css')
|
|
10
|
-
*/
|
|
11
|
-
appendTo?: (assetPath: string) => boolean;
|
|
12
12
|
/**
|
|
13
13
|
* Specify where stylex will be imported from
|
|
14
14
|
*
|
|
@@ -22,18 +22,19 @@ interface StyleXPluginOption {
|
|
|
22
22
|
*/
|
|
23
23
|
useCSSLayers?: boolean;
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* Next.js Mode
|
|
26
|
+
*
|
|
27
|
+
* @default false
|
|
26
28
|
*/
|
|
27
|
-
|
|
29
|
+
nextjsMode?: boolean;
|
|
28
30
|
}
|
|
29
31
|
type RegisterStyleXRules = (resourcePath: string, stylexRules: Rule[]) => void;
|
|
30
32
|
declare class StyleXPlugin {
|
|
31
33
|
static stylexLoader: string;
|
|
32
34
|
stylexRules: Map<string, readonly Rule[]>;
|
|
33
|
-
readonly stylexImports: string[];
|
|
34
35
|
useCSSLayers: boolean;
|
|
35
|
-
|
|
36
|
-
constructor({ stylexImports, useCSSLayers, stylexOption }?: StyleXPluginOption);
|
|
36
|
+
loaderOption: StyleXLoaderOptions;
|
|
37
|
+
constructor({ stylexImports, useCSSLayers, stylexOption, nextjsMode }?: StyleXPluginOption);
|
|
37
38
|
apply(compiler: webpack.Compiler): void;
|
|
38
39
|
}
|
|
39
40
|
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ var path = require('path');
|
|
|
6
6
|
const PLUGIN_NAME = 'stylex';
|
|
7
7
|
const VIRTUAL_CSS_PATH = require.resolve('./stylex.virtual.css');
|
|
8
8
|
const VIRTUAL_CSS_PATTERN = /stylex\.virtual\.css/;
|
|
9
|
+
const STYLEX_CHUNK_NAME = '_stylex-webpack-generated';
|
|
9
10
|
// Webpack does not export these constants
|
|
10
11
|
// https://github.com/webpack/webpack/blob/b67626c7b4ffed8737d195b27c8cea1e68d58134/lib/OptimizationStages.js#L8
|
|
11
12
|
const OPTIMIZE_CHUNKS_STAGE_ADVANCED = 10;
|
|
@@ -45,6 +46,7 @@ class StyleXPlugin {
|
|
|
45
46
|
// stylex-loader adds virtual css import (which triggers virtual-loader)
|
|
46
47
|
// This prevents "stylex.virtual.css" files from being tree shaken by forcing
|
|
47
48
|
// "sideEffects" setting.
|
|
49
|
+
// TODO-RSPACK: rspack does support normalModuleFactory, we need to test this out
|
|
48
50
|
compiler.hooks.normalModuleFactory.tap(PLUGIN_NAME, (nmf)=>{
|
|
49
51
|
nmf.hooks.createModule.tap(PLUGIN_NAME, (createData)=>{
|
|
50
52
|
const modPath = createData.matchResource ?? createData.resourceResolveData?.path;
|
|
@@ -56,7 +58,7 @@ class StyleXPlugin {
|
|
|
56
58
|
});
|
|
57
59
|
});
|
|
58
60
|
const { Compilation, NormalModule, sources } = compiler.webpack;
|
|
59
|
-
const {
|
|
61
|
+
const { RawSource } = sources;
|
|
60
62
|
// Apply loader to JS modules
|
|
61
63
|
compiler.hooks.make.tap(PLUGIN_NAME, (compilation)=>{
|
|
62
64
|
NormalModule.getCompilationHooks(compilation).loader.tap(PLUGIN_NAME, (loaderContext, mod)=>{
|
|
@@ -73,10 +75,7 @@ class StyleXPlugin {
|
|
|
73
75
|
// our loader before anything else.
|
|
74
76
|
mod.loaders.push({
|
|
75
77
|
loader: stylexLoaderPath,
|
|
76
|
-
options:
|
|
77
|
-
stylexImports: this.stylexImports,
|
|
78
|
-
stylexOption: this.stylexOption
|
|
79
|
-
},
|
|
78
|
+
options: this.loaderOption,
|
|
80
79
|
ident: null,
|
|
81
80
|
type: null
|
|
82
81
|
});
|
|
@@ -88,7 +87,9 @@ class StyleXPlugin {
|
|
|
88
87
|
name: PLUGIN_NAME,
|
|
89
88
|
stage: OPTIMIZE_CHUNKS_STAGE_ADVANCED
|
|
90
89
|
}, ()=>{
|
|
91
|
-
|
|
90
|
+
// TODO-RSPACK: rspack doesn't support manually manipulating chunks
|
|
91
|
+
// Find a way to do this in rspack
|
|
92
|
+
const stylexChunk = compilation.namedChunks.get(STYLEX_CHUNK_NAME) || compilation.addChunk(STYLEX_CHUNK_NAME);
|
|
92
93
|
const matchingChunks = new Set();
|
|
93
94
|
let moduleIndex = 0;
|
|
94
95
|
for (const module of compilation.modules){
|
|
@@ -113,36 +114,47 @@ class StyleXPlugin {
|
|
|
113
114
|
name: PLUGIN_NAME,
|
|
114
115
|
stage: Compilation.PROCESS_ASSETS_STAGE_PRE_PROCESS
|
|
115
116
|
}, (assets)=>{
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
// on previous step, we create a "stylex" chunk to hold all virtual stylex css
|
|
118
|
+
// the chunk contains all css chunks generated by mini-css-extract-plugin
|
|
119
|
+
// TODO-RSPACK: once again, rspack doesn't have this
|
|
120
|
+
const stylexChunk = compilation.namedChunks.get(STYLEX_CHUNK_NAME);
|
|
121
|
+
if (stylexChunk == null) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Let's find the css file that belongs to the stylex chunk
|
|
125
|
+
const cssAssetDetails = Object.entries(assets).find(([assetName])=>stylexChunk.files.has(assetName));
|
|
126
|
+
if (!cssAssetDetails) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const stylexCSS = getStyleXRules(this.stylexRules, this.useCSSLayers);
|
|
130
|
+
if (stylexCSS == null) {
|
|
131
|
+
return;
|
|
123
132
|
}
|
|
133
|
+
compilation.updateAsset(cssAssetDetails[0], new RawSource(stylexCSS));
|
|
124
134
|
});
|
|
125
135
|
});
|
|
126
136
|
}
|
|
127
137
|
constructor({ stylexImports = [
|
|
128
138
|
'stylex',
|
|
129
139
|
'@stylexjs/stylex'
|
|
130
|
-
], useCSSLayers = false, stylexOption = {} } = {}){
|
|
140
|
+
], useCSSLayers = false, stylexOption = {}, nextjsMode = false } = {}){
|
|
131
141
|
_define_property(this, "stylexRules", new Map());
|
|
132
|
-
_define_property(this, "stylexImports", []);
|
|
133
142
|
_define_property(this, "useCSSLayers", void 0);
|
|
134
|
-
_define_property(this, "
|
|
143
|
+
_define_property(this, "loaderOption", void 0);
|
|
135
144
|
this.useCSSLayers = useCSSLayers;
|
|
136
|
-
this.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
145
|
+
this.loaderOption = {
|
|
146
|
+
stylexImports,
|
|
147
|
+
stylexOption: {
|
|
148
|
+
dev: process.env.NODE_ENV === 'development',
|
|
149
|
+
useRemForFontSize: true,
|
|
150
|
+
runtimeInjection: false,
|
|
151
|
+
genConditionalClasses: true,
|
|
152
|
+
treeshakeCompensation: true,
|
|
153
|
+
importSources: stylexImports,
|
|
154
|
+
...stylexOption
|
|
155
|
+
},
|
|
156
|
+
nextjsMode
|
|
144
157
|
};
|
|
145
|
-
this.stylexImports = stylexImports;
|
|
146
158
|
}
|
|
147
159
|
}
|
|
148
160
|
_define_property(StyleXPlugin, "stylexLoader", stylexLoaderPath);
|
package/dist/next.d.ts
CHANGED
|
@@ -3,12 +3,6 @@ import { Options } from '@stylexjs/babel-plugin';
|
|
|
3
3
|
|
|
4
4
|
interface StyleXPluginOption {
|
|
5
5
|
stylexOption?: Partial<Options>;
|
|
6
|
-
/**
|
|
7
|
-
* Specify where to inject the StyleX generated CSS
|
|
8
|
-
*
|
|
9
|
-
* @default (filename) => filename.endsWith('stylex.css')
|
|
10
|
-
*/
|
|
11
|
-
appendTo?: (assetPath: string) => boolean;
|
|
12
6
|
/**
|
|
13
7
|
* Specify where stylex will be imported from
|
|
14
8
|
*
|
|
@@ -22,9 +16,11 @@ interface StyleXPluginOption {
|
|
|
22
16
|
*/
|
|
23
17
|
useCSSLayers?: boolean;
|
|
24
18
|
/**
|
|
25
|
-
*
|
|
19
|
+
* Next.js Mode
|
|
20
|
+
*
|
|
21
|
+
* @default false
|
|
26
22
|
*/
|
|
27
|
-
|
|
23
|
+
nextjsMode?: boolean;
|
|
28
24
|
}
|
|
29
25
|
|
|
30
26
|
declare const withStyleX: (pluginOptions?: StyleXPluginOption) => (nextConfig?: NextConfig) => NextConfig;
|
package/dist/next.js
CHANGED
|
@@ -30,21 +30,23 @@ const getNextMiniCssExtractPlugin = (isDev)=>{
|
|
|
30
30
|
};
|
|
31
31
|
// Adopt from Next.js' getGlobalCssLoader
|
|
32
32
|
// https://github.com/vercel/next.js/blob/d61b0761efae09bd9cb1201ff134ed8950d9deca/packages/next/src/build/webpack/config/blocks/css/loaders/global.ts#L7
|
|
33
|
-
function getStyleXVirtualCssLoader(
|
|
33
|
+
function getStyleXVirtualCssLoader(ctx, MiniCssExtractPlugin) {
|
|
34
34
|
const loaders = [];
|
|
35
35
|
// Adopt from Next.js' getClientStyleLoader
|
|
36
36
|
// https://github.com/vercel/next.js/blob/56d35ede8ed2ab25fa8e29583d4e81e3e76a0e29/packages/next/src/build/webpack/config/blocks/css/loaders/global.ts#L7
|
|
37
|
-
if (!
|
|
37
|
+
if (!ctx.isServer) {
|
|
38
38
|
// https://github.com/vercel/next.js/blob/56d35ede8ed2ab25fa8e29583d4e81e3e76a0e29/packages/next/src/build/webpack/config/blocks/css/loaders/global.ts#L18
|
|
39
39
|
// https://github.com/vercel/next.js/blob/56d35ede8ed2ab25fa8e29583d4e81e3e76a0e29/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts#L3
|
|
40
40
|
loaders.push({
|
|
41
41
|
loader: MiniCssExtractPlugin.loader,
|
|
42
42
|
options: {
|
|
43
|
-
publicPath: `${
|
|
43
|
+
publicPath: `${ctx.assetPrefix}/_next/`,
|
|
44
44
|
esModule: false
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
+
// We don't actually need to run postcss-loader or css-loader here
|
|
49
|
+
// As stylex virtual css won't contain any real css
|
|
48
50
|
return loaders;
|
|
49
51
|
}
|
|
50
52
|
const withStyleX = (pluginOptions)=>(nextConfig = {})=>{
|
|
@@ -107,7 +109,9 @@ const withStyleX = (pluginOptions)=>(nextConfig = {})=>{
|
|
|
107
109
|
stylexOption: {
|
|
108
110
|
...pluginOptions?.stylexOption,
|
|
109
111
|
dev: ctx.dev
|
|
110
|
-
}
|
|
112
|
+
},
|
|
113
|
+
// Enforce nextjsMode to true
|
|
114
|
+
nextjsMode: true
|
|
111
115
|
}));
|
|
112
116
|
return config;
|
|
113
117
|
}
|
package/dist/stylex-loader.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var core = require('@babel/core');
|
|
4
4
|
var stylexBabelPlugin = require('@stylexjs/babel-plugin');
|
|
5
|
+
var loaderUtils = require('loader-utils');
|
|
5
6
|
|
|
6
7
|
function stringifyRequest(loaderContext, request) {
|
|
7
8
|
return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request));
|
|
@@ -16,7 +17,7 @@ const isSupplementedLoaderContext = (context)=>{
|
|
|
16
17
|
const PLUGIN_NAME = 'stylex';
|
|
17
18
|
async function stylexLoader(inputCode, inputSourceMap) {
|
|
18
19
|
const callback = this.async();
|
|
19
|
-
const { stylexImports, stylexOption } = this.getOptions();
|
|
20
|
+
const { stylexImports, stylexOption, nextjsMode } = this.getOptions();
|
|
20
21
|
// bail out early if the input doesn't contain stylex imports
|
|
21
22
|
if (!stylexImports.some((importName)=>inputCode.includes(importName))) {
|
|
22
23
|
return callback(null, inputCode, inputSourceMap);
|
|
@@ -50,8 +51,23 @@ async function stylexLoader(inputCode, inputSourceMap) {
|
|
|
50
51
|
}
|
|
51
52
|
// this.stylexRules[filename] = metadata.stylex;
|
|
52
53
|
logger?.debug(`Read stylex styles from ${this.resourcePath}:`, metadata.stylex);
|
|
54
|
+
// TODO: rspack doesn't support custom loader context
|
|
55
|
+
// Find a better way to register stylex rules to the compiler instance
|
|
53
56
|
this.StyleXWebpackContextKey.registerStyleXRules(this.resourcePath, metadata.stylex);
|
|
54
|
-
const
|
|
57
|
+
const serializedStyleXRules = JSON.stringify(metadata.stylex);
|
|
58
|
+
if (!nextjsMode) {
|
|
59
|
+
// Normal webpack mode
|
|
60
|
+
// We generate a virtual css file that looks like it is relative to the source
|
|
61
|
+
const virtualFileName = loaderUtils.interpolateName(this, '[path][name].[hash:base64:8].stylex.virtual.css', {
|
|
62
|
+
content: serializedStyleXRules
|
|
63
|
+
});
|
|
64
|
+
const virtualCssRequest = stringifyRequest(this, `${virtualFileName}!=!${VIRTUAL_CSS_PATH}?${serializedStyleXRules}`);
|
|
65
|
+
const postfix = `\nimport ${virtualCssRequest};`;
|
|
66
|
+
return callback(null, code + postfix, map ?? undefined);
|
|
67
|
+
}
|
|
68
|
+
// Next.js App Router doesn't support inline matchResource and inline loaders
|
|
69
|
+
// So we adapt Next.js' "external" css import approach instead
|
|
70
|
+
const virtualCssRequest = stringifyRequest(this, `${VIRTUAL_CSS_PATH}?${serializedStyleXRules}`);
|
|
55
71
|
const postfix = `\nimport ${virtualCssRequest};`;
|
|
56
72
|
return callback(null, code + postfix, map ?? undefined);
|
|
57
73
|
} catch (error) {
|
package/package.json
CHANGED