@stylexswc/nextjs-plugin 0.2.4 → 0.3.0-rc.1

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/README.md CHANGED
@@ -1,35 +1,41 @@
1
- # SWC Stylex plugin for Next.js
1
+ # Next.js plugin with NAPI-RS StyleX compiler integration
2
2
 
3
3
  Next.js plugin for an unofficial
4
- [`StyleX SWC`](https://github.com/dwlad90/stylex-swc-plugin/tree/master/crates/stylex-swc-plugin)
5
- plugin.
4
+ [`napi-rs`](https://github.com/dwlad90/stylex-swc-plugin/tree/master/crates/stylex-rs-compiler)
5
+ compiler that includes the StyleX SWC code transformation under the hood.
6
6
 
7
- ## Why SWC instead of Babel
7
+ ## Overview
8
8
 
9
- Since version 12, Next.js uses SWC Compiler by default.
10
- [According to Vercel](https://nextjs.org/docs/architecture/nextjs-compiler),
11
- compilation using the SWC Compiler is 17x faster than Babel.
9
+ This package combines two solutions to enhance your Next.js development experience with StyleX:
12
10
 
13
- However, if you have a Babel config, the application will out put of SWC
14
- Compiler and continue to use Babel.
11
+ ### StyleX SWC Plugin
15
12
 
16
- This plugin allows us to use StyleX and take advantage of SWC Compiler.
13
+ * Integrates StyleX with the SWC compiler, potentially leading to faster build times compared to using Babel.
14
+ * Maintains high compatibility with official StyleX tests, ensuring a reliable experience.
15
+ * Integrates seamlessly with Next.js SWC Compiler for a streamlined workflow.
17
16
 
18
- **The usage of StyleX does not change**, all changes are internal. All you need
19
- to do, is install SWC StyleX plugin and update Next.js config.
17
+ ### Stylex NAPI-RS Compiler
18
+
19
+ * Utilizes NAPI-RS to compile StyleX code, offering advantages over the SWC plugin approach.
20
+ * Provides access to StyleX metadata and source maps, enabling advanced plugin and tool development.
21
+
22
+ ## Why choose this approach?
23
+
24
+ * Leverage SWC's speed: Benefit from Next.js's default SWC compiler for potentially faster build times.
25
+ * Maintain StyleX familiarity: The usage of StyleX remains unchanged for developers.
20
26
 
21
27
  ## Installation
22
28
 
23
- Install the package and SWC plugin by using:
29
+ To install the package, run the following command:
24
30
 
25
31
  ```bash
26
32
  npm install --save-dev @stylexswc/nextjs-plugin
27
33
  ```
28
34
 
29
- Please install `@stylexswc/swc-plugin` if you haven't done so already:
35
+ Please install `@stylexswc/rs-compiler` if you haven't done so already:
30
36
 
31
37
  ```bash
32
- npm install --save-dev @stylexswc/swc-plugin
38
+ npm install --save-dev @stylexswc/rs-compiler
33
39
  ```
34
40
 
35
41
  ## Usage
@@ -46,34 +52,28 @@ const nextConfig = {
46
52
  transpilePackages: ['@stylexjs/open-props'],
47
53
  // Optionally, add any other Next.js config below
48
54
  swcMinify: true,
49
- experimental: {
50
- swcPlugins: [
51
- '@stylexswc/swc-plugin',
52
- {
53
- dev: false,
54
- runtimeInjection: false,
55
- genConditionalClasses: true,
56
- treeshakeCompensation: true,
57
- unstable_moduleResolution: {
58
- type: 'commonJS',
59
- rootDir: __dirname,
60
- },
61
- },
62
- ],
63
- },
64
55
  };
65
56
 
66
57
  module.exports = stylexPlugin({
67
58
  rootDir: __dirname,
59
+ // Stylex RS compiler options
60
+ dev: false,
61
+ runtimeInjection: false,
62
+ genConditionalClasses: true,
63
+ treeshakeCompensation: true,
64
+ unstable_moduleResolution: {
65
+ type: 'commonJS',
66
+ rootDir: __dirname,
67
+ },
68
68
  })(nextConfig);
69
69
  ```
70
70
 
71
71
  ## Examples
72
72
 
73
- - [Example repo](https://github.com/Dwlad90/nextjs-app-dir-stylex)
74
- - [CodeSandbox with example repo](https://codesandbox.io/p/github/Dwlad90/nextjs-app-dir-stylex/main)
73
+ * [Example repo](https://github.com/Dwlad90/nextjs-app-dir-stylex)
74
+ * [CodeSandbox with example repo](https://codesandbox.io/p/github/Dwlad90/nextjs-app-dir-stylex/main)
75
75
 
76
76
  ## Documentation
77
77
 
78
- - [StyleX Documentation](https://stylexjs.com)
79
- - [SWC plugin for StyleX](https://github.com/Dwlad90/stylex-swc-plugin/tree/master/packages/swc-plugin)
78
+ * [StyleX Documentation](https://stylexjs.com)
79
+ * [SWC plugin for StyleX](https://github.com/Dwlad90/stylex-swc-plugin/tree/master/packages/swc-plugin)
@@ -1,19 +1,19 @@
1
1
  import type { Compiler } from 'webpack';
2
+ import type { StyleXOptions } from '@stylexswc/rs-compiler';
2
3
  declare class StylexPlugin {
3
4
  filesInLastRun: any;
4
- filePath: any;
5
- dev: any;
5
+ filePath?: string | null;
6
+ dev: boolean;
6
7
  appendTo: any;
7
- filename: any;
8
- babelConfig: any;
8
+ filename?: string;
9
9
  stylexImports: any[];
10
- babelPlugin: any;
11
10
  useCSSLayers: any;
12
- constructor({ dev, appendTo, filename, stylexImports, useCSSLayers, }?: any);
11
+ rsOptions: StyleXOptions;
12
+ constructor({ dev, appendTo, filename, stylexImports, useCSSLayers, rsOptions, }?: any);
13
13
  apply(compiler: Compiler): void;
14
14
  transformCode(inputCode: string, filename: string, logger: any): Promise<{
15
15
  code: string;
16
- map: null;
16
+ map: string | undefined;
17
17
  } | {
18
18
  code: string;
19
19
  map?: undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"custom-webpack-plugin.d.ts","sourceRoot":"","sources":["../src/custom-webpack-plugin.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,SAAS,CAAC;AAetD,cAAM,YAAY;IAChB,cAAc,EAAE,GAAG,CAAQ;IAC3B,QAAQ,EAAE,GAAG,CAAQ;IACrB,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;IACd,WAAW,EAAE,GAAG,CAAC;IACjB,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,WAAW,EAAE,GAAG,CAAC;IACjB,YAAY,EAAE,GAAG,CAAC;gBAEN,EACV,GAAgB,EAChB,QAAQ,EACR,QAAsD,EACtD,aAA8C,EAC9C,YAAoB,GACrB,GAAE,GAAQ;IASX,KAAK,CAAC,QAAQ,EAAE,QAAQ;IAgGlB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG;;;;;;;CA2DrE;AACD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"custom-webpack-plugin.d.ts","sourceRoot":"","sources":["../src/custom-webpack-plugin.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,SAAS,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAc5D,cAAM,YAAY;IAChB,cAAc,EAAE,GAAG,CAAQ;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,YAAY,EAAE,GAAG,CAAC;IAClB,SAAS,EAAE,aAAa,CAAC;gBAEb,EACV,GAAgB,EAChB,QAAQ,EACR,QAAsD,EACtD,aAA8C,EAC9C,YAAoB,EACpB,SAAc,GACf,GAAE,GAAQ;IAUX,KAAK,CAAC,QAAQ,EAAE,QAAQ;IA2FlB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG;;;;;;;CA0CrE;AACD,eAAe,YAAY,CAAC"}
@@ -5,11 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const path_1 = __importDefault(require("path"));
7
7
  const babel_plugin_1 = __importDefault(require("@stylexjs/babel-plugin"));
8
+ const rs_compiler_1 = require("@stylexswc/rs-compiler");
8
9
  const webpack_1 = __importDefault(require("webpack"));
9
10
  const promises_1 = __importDefault(require("fs/promises"));
10
11
  const { NormalModule, Compilation } = webpack_1.default;
11
12
  const PLUGIN_NAME = 'stylex';
12
- const IS_DEV_ENV = process.env.NODE_ENV === 'development' || process.env.BABEL_ENV === 'development';
13
+ const IS_DEV_ENV = process.env.NODE_ENV === 'development';
13
14
  const { RawSource, ConcatSource } = webpack_1.default.sources;
14
15
  const stylexRules = {};
15
16
  const cssFiles = new Set();
@@ -20,16 +21,16 @@ class StylexPlugin {
20
21
  dev;
21
22
  appendTo;
22
23
  filename;
23
- babelConfig;
24
24
  stylexImports;
25
- babelPlugin;
26
25
  useCSSLayers;
27
- constructor({ dev = IS_DEV_ENV, appendTo, filename = appendTo == null ? 'stylex.css' : undefined, stylexImports = ['stylex', '@stylexjs/stylex'], useCSSLayers = false, } = {}) {
26
+ rsOptions;
27
+ constructor({ dev = IS_DEV_ENV, appendTo, filename = appendTo == null ? 'stylex.css' : undefined, stylexImports = ['stylex', '@stylexjs/stylex'], useCSSLayers = false, rsOptions = {}, } = {}) {
28
28
  this.dev = dev;
29
29
  this.appendTo = appendTo;
30
30
  this.filename = filename;
31
31
  this.stylexImports = stylexImports;
32
32
  this.useCSSLayers = useCSSLayers;
33
+ this.rsOptions = rsOptions;
33
34
  }
34
35
  apply(compiler) {
35
36
  compiler.hooks.make.tap(PLUGIN_NAME, compilation => {
@@ -40,9 +41,8 @@ class StylexPlugin {
40
41
  /\.jsx?/.test(path_1.default.extname(module.resource)) ||
41
42
  // TypeScript modules
42
43
  /\.tsx?/.test(path_1.default.extname(module.resource))) {
43
- // We use .push() here instead of .unshift()
44
- // Webpack usually runs loaders in reverse order and we want to ideally run
45
- // our loader before anything else.
44
+ // We use .unshift() and not .push() like original babel plugin
45
+ // because we want to run other transformations first, e.g. custom SWC plugins.
46
46
  module.loaders.unshift({
47
47
  loader: path_1.default.resolve(__dirname, 'custom-webpack-loader.js'),
48
48
  options: { stylexPlugin: this },
@@ -63,8 +63,8 @@ class StylexPlugin {
63
63
  // Take styles for the modules that were included in the last compilation.
64
64
  const allRules = Object.keys(stylexRules)
65
65
  .map(filename => stylexRules[filename])
66
- .filter(Boolean)
67
- .flat();
66
+ .flat()
67
+ .filter((rule) => !!rule);
68
68
  return babel_plugin_1.default.processStylexRules(allRules, this.useCSSLayers);
69
69
  };
70
70
  if (this.appendTo) {
@@ -78,12 +78,9 @@ class StylexPlugin {
78
78
  const stylexCSS = getStyleXRules();
79
79
  if (cssFileName && stylexCSS != null) {
80
80
  this.filePath = path_1.default.join(process.cwd(), '.next', cssFileName);
81
- const source = assets?.[cssFileName]?.source();
82
- if (source) {
83
- const updatedSource = new ConcatSource(new RawSource(source), new RawSource(stylexCSS));
84
- compilation.updateAsset(cssFileName, updatedSource);
85
- compilers.add(compiler);
86
- }
81
+ const updatedSource = new ConcatSource(new RawSource(assets[cssFileName]?.source() || ''), new RawSource(stylexCSS));
82
+ compilation.updateAsset(cssFileName, updatedSource);
83
+ compilers.add(compiler);
87
84
  }
88
85
  });
89
86
  }
@@ -92,7 +89,7 @@ class StylexPlugin {
92
89
  compilation.hooks.additionalAssets.tap(PLUGIN_NAME, () => {
93
90
  try {
94
91
  const collectedCSS = getStyleXRules();
95
- if (collectedCSS) {
92
+ if (collectedCSS && this.filename) {
96
93
  console.log('emitting asset', this.filename, collectedCSS);
97
94
  compilation.emitAsset(this.filename, new RawSource(collectedCSS));
98
95
  promises_1.default.writeFile(this.filename, collectedCSS).then(() => console.log('wrote file', this.filename));
@@ -113,22 +110,13 @@ class StylexPlugin {
113
110
  if (inputCode.includes('Welcome to my MDX page'))
114
111
  console.log('originalSource: ', originalSource);
115
112
  if (this.stylexImports.some(importName => originalSource.includes(importName))) {
116
- let metadataStr = '[]';
117
- const code = originalSource.replace(/\/\/*__stylex_metadata_start__(?<metadata>.+)__stylex_metadata_end__/, (...args) => {
118
- metadataStr = args.at(-1)?.metadata.split('"__stylex_metadata_end__')[0];
119
- return '';
120
- });
121
- const metadata = { stylex: [] };
122
- try {
123
- metadata.stylex = JSON.parse(metadataStr);
124
- }
125
- catch (e) {
126
- console.error('error parsing metadata', e);
127
- }
128
- const map = null;
113
+ let result = (0, rs_compiler_1.transform)(filename, inputCode, this.rsOptions);
114
+ const metadata = result?.metadata;
115
+ const code = result.code;
116
+ const map = result.map;
129
117
  if (metadata.stylex != null && metadata.stylex.length > 0) {
130
118
  const oldRules = stylexRules[filename] || [];
131
- stylexRules[filename] = metadata.stylex?.map((rule) => [rule.class_name, rule.style, rule.priority]);
119
+ stylexRules[filename] = metadata.stylex;
132
120
  logger.debug(`Read stylex styles from ${filename}:`, metadata.stylex);
133
121
  const oldClassNames = new Set(oldRules.map(rule => rule[0]));
134
122
  const newClassNames = new Set(metadata.stylex.map(rule => rule[0]));
@@ -145,8 +133,8 @@ class StylexPlugin {
145
133
  });
146
134
  });
147
135
  }
148
- return { code, map };
149
136
  }
137
+ return { code, map };
150
138
  }
151
139
  return { code: inputCode };
152
140
  }
package/dist/index.d.ts CHANGED
@@ -2,7 +2,12 @@ import type { Configuration } from 'webpack';
2
2
  import type { NextConfig } from 'next';
3
3
  import type { ConfigurationContext } from 'next/dist/build/webpack/config/utils';
4
4
  import type { WebpackConfigContext } from 'next/dist/server/config-shared';
5
- declare function StylexNextJSPlugin({ rootDir, filename, ...pluginOptions }: any): (nextConfig?: NextConfig) => {
5
+ import type { StyleXOptions } from '@stylexswc/rs-compiler';
6
+ interface StylexNextJSPluginOptions extends StyleXOptions {
7
+ rootDir: string;
8
+ filename?: string;
9
+ }
10
+ declare function StylexNextJSPlugin({ rootDir, filename, ...pluginOptions }: StylexNextJSPluginOptions): (nextConfig?: NextConfig) => {
6
11
  transpilePackages: string[];
7
12
  webpack(config: Configuration & ConfigurationContext, options: WebpackConfigContext): Configuration & ConfigurationContext;
8
13
  exportPathMap?: ((defaultMap: import("next/dist/server/config-shared").ExportPathMap, ctx: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAG3E,iBAAS,kBAAkB,CAAC,EAAE,OAAO,EAAE,QAA8B,EAAE,GAAG,aAAa,EAAE,EAAE,GAAG,iBACxE,UAAU;;oBAIV,aAAa,GAAG,oBAAoB,WAAW,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CxF;AAED,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAI5D,UAAU,yBAA0B,SAAQ,aAAa;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,iBAAS,kBAAkB,CAAC,EAC1B,OAAO,EACP,QAA8B,EAC9B,GAAG,aAAa,EACjB,EAAE,yBAAyB,iBACN,UAAU;;oBAIV,aAAa,GAAG,oBAAoB,WAAW,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CxF;AAED,eAAe,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ function StylexNextJSPlugin({ rootDir, filename = 'stylex-bundle.css', ...plugin
39
39
  appendTo: (name) => name.endsWith('.css'),
40
40
  filename,
41
41
  dev,
42
- ...pluginOptions,
42
+ rsOptions: pluginOptions,
43
43
  };
44
44
  const stylexPlugin = new custom_webpack_plugin_1.default(webpackPluginOptions);
45
45
  config.plugins?.push(stylexPlugin);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stylexswc/nextjs-plugin",
3
- "description": "Stylex NextJS plugin with swc plugin",
4
- "version": "0.2.4",
3
+ "description": "Stylex NextJS plugin with NAPI-RS compiler",
4
+ "version": "0.3.0-rc.1",
5
5
  "config": {
6
6
  "scripty": {
7
7
  "path": "../../scripts/packages"
@@ -15,8 +15,9 @@
15
15
  "react": "^18.2.0",
16
16
  "react-dom": "^18.2.0",
17
17
  "webpack": "^5.88.2",
18
- "@stylexswc/eslint-config": "0.2.4",
19
- "@stylexswc/typescript-config": "0.2.4"
18
+ "@stylexswc/typescript-config": "0.3.0-rc.1",
19
+ "@stylexswc/rs-compiler": "0.3.0-rc.1",
20
+ "@stylexswc/eslint-config": "0.3.0-rc.1"
20
21
  },
21
22
  "files": [
22
23
  "dist"
@@ -35,9 +36,10 @@
35
36
  },
36
37
  "private": false,
37
38
  "publishConfig": {
39
+ "registry": "https://registry.npmjs.org/",
38
40
  "access": "public"
39
41
  },
40
- "repository": "dwlad90/stylex-swc-plugin",
42
+ "repository": "https://github.com/Dwlad90/stylex-swc-plugin",
41
43
  "sideEffects": false,
42
44
  "scripts": {
43
45
  "build": "scripty --ts",