@quilted/rollup 0.1.5 → 0.1.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @quilted/rollup
2
2
 
3
+ ## 0.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [`f450b0e4`](https://github.com/lemonmade/quilt/commit/f450b0e4ff5026dfd98f8fa044fb1fa26c0861bf) Thanks [@lemonmade](https://github.com/lemonmade)! - Actually fix Babel `target` option
8
+
9
+ - [`29564cdc`](https://github.com/lemonmade/quilt/commit/29564cdcd0f82cb5bb2eee6d76ad9314db28d14c) Thanks [@lemonmade](https://github.com/lemonmade)! - Add asset plugins
10
+
11
+ ## 0.1.6
12
+
13
+ ### Patch Changes
14
+
15
+ - [`a2615aa0`](https://github.com/lemonmade/quilt/commit/a2615aa06a3cd146111996c8401466c5d8b9be09) Thanks [@lemonmade](https://github.com/lemonmade)! - Default to GraphQL in app server
16
+
17
+ - [`2a0b85fe`](https://github.com/lemonmade/quilt/commit/2a0b85fe4a2d07ce107e52a3f246728c7c38fbf2) Thanks [@lemonmade](https://github.com/lemonmade)! - Add CSS plugin to app
18
+
19
+ - [`a2615aa0`](https://github.com/lemonmade/quilt/commit/a2615aa06a3cd146111996c8401466c5d8b9be09) Thanks [@lemonmade](https://github.com/lemonmade)! - Remove 'use client' warnings
20
+
3
21
  ## 0.1.5
4
22
 
5
23
  ### Patch Changes
package/build/cjs/app.cjs CHANGED
@@ -34,20 +34,33 @@ async function quiltAppBrowser({
34
34
  graphql = true
35
35
  } = {}) {
36
36
  const mode = (typeof env === 'object' ? env?.mode : undefined) ?? 'production';
37
- const minify = assets?.minify ?? true;
37
+ const minify = assets?.minify ?? mode === 'production';
38
+ const baseURL = assets?.baseURL ?? '/assets/';
38
39
  const [{
39
40
  visualizer
41
+ }, {
42
+ assetManifest
40
43
  }, {
41
44
  sourceCode
45
+ }, {
46
+ css
42
47
  }, {
43
48
  rawAssets,
44
49
  staticAssets
45
50
  }, {
46
51
  systemJS
47
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), Promise.resolve().then(function () { return require('./features/source-code.cjs'); }), Promise.resolve().then(function () { return require('./features/assets.cjs'); }), Promise.resolve().then(function () { return require('./features/system-js.cjs'); }), rollup.getNodePlugins()]);
48
- const plugins = [...nodePlugins, systemJS(), sourceCode({
52
+ }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('@quilted/assets/rollup'), Promise.resolve().then(function () { return require('./features/source-code.cjs'); }), Promise.resolve().then(function () { return require('./features/css.cjs'); }), Promise.resolve().then(function () { return require('./features/assets.cjs'); }), Promise.resolve().then(function () { return require('./features/system-js.cjs'); }), rollup.getNodePlugins()]);
53
+ const plugins = [...nodePlugins, systemJS({
54
+ minify
55
+ }), sourceCode({
49
56
  mode
50
- }), rawAssets(), staticAssets()];
57
+ }), css({
58
+ minify,
59
+ emit: true
60
+ }), rawAssets(), staticAssets({
61
+ baseURL,
62
+ emit: true
63
+ })];
51
64
  if (env) {
52
65
  const {
53
66
  magicModuleEnv,
@@ -89,15 +102,28 @@ async function quiltAppBrowser({
89
102
  } = await import('rollup-plugin-esbuild');
90
103
  plugins.push(minify());
91
104
  }
92
- plugins.push(visualizer({
105
+ plugins.push(
106
+ // @ts-expect-error The plugin still depends on Rollup 3
107
+ assetManifest({
108
+ baseUrl: baseURL,
109
+ path: path__namespace.resolve(`build/manifests/assets.json`)
110
+ }), visualizer({
93
111
  template: 'treemap',
94
112
  open: false,
95
113
  brotliSize: true,
96
- filename: path__namespace.resolve(`reports/bundle-visualizer.html`)
114
+ filename: path__namespace.resolve(`build/reports/bundle-visualizer.html`)
97
115
  }));
98
116
  return {
99
117
  input: entry,
100
118
  plugins,
119
+ onwarn(warning, defaultWarn) {
120
+ // Removes annoying warnings for React-focused libraries that
121
+ // include 'use client' directives.
122
+ if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && /['"]use client['"]/.test(warning.message)) {
123
+ return;
124
+ }
125
+ defaultWarn(warning);
126
+ },
101
127
  output: {
102
128
  // format: isESM ? 'esm' : 'systemjs',
103
129
  format: 'esm',
@@ -112,7 +138,7 @@ async function quiltAppBrowser({
112
138
  async function quiltAppServer({
113
139
  app,
114
140
  env,
115
- graphql,
141
+ graphql = true,
116
142
  entry = constants.MAGIC_MODULE_ENTRY,
117
143
  minify = false
118
144
  } = {}) {
@@ -121,14 +147,19 @@ async function quiltAppServer({
121
147
  visualizer
122
148
  }, {
123
149
  sourceCode
150
+ }, {
151
+ css
124
152
  }, {
125
153
  rawAssets,
126
154
  staticAssets
127
155
  }, {
128
156
  magicModuleRequestRouterEntry
129
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), Promise.resolve().then(function () { return require('./features/source-code.cjs'); }), Promise.resolve().then(function () { return require('./features/assets.cjs'); }), Promise.resolve().then(function () { return require('./features/request-router.cjs'); }), rollup.getNodePlugins()]);
157
+ }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), Promise.resolve().then(function () { return require('./features/source-code.cjs'); }), Promise.resolve().then(function () { return require('./features/css.cjs'); }), Promise.resolve().then(function () { return require('./features/assets.cjs'); }), Promise.resolve().then(function () { return require('./features/request-router.cjs'); }), rollup.getNodePlugins()]);
130
158
  const plugins = [...nodePlugins, sourceCode({
131
159
  mode
160
+ }), css({
161
+ emit: false,
162
+ minify
132
163
  }), rawAssets(), staticAssets({
133
164
  emit: false
134
165
  })];
@@ -180,7 +211,7 @@ async function quiltAppServer({
180
211
  template: 'treemap',
181
212
  open: false,
182
213
  brotliSize: true,
183
- filename: path__namespace.resolve(`reports/bundle-visualizer.html`)
214
+ filename: path__namespace.resolve(`build/reports/bundle-visualizer.html`)
184
215
  }));
185
216
  return {
186
217
  input: entry,
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var path = require('node:path');
4
- var promises = require('node:fs/promises');
4
+ var fs = require('node:fs/promises');
5
5
  var node_crypto = require('node:crypto');
6
6
  var mime = require('mrmime');
7
7
 
@@ -48,7 +48,7 @@ function rawAssets() {
48
48
  }
49
49
  const moduleId = cleanModuleIdentifier(id);
50
50
  this.addWatchFile(moduleId);
51
- const file = await promises.readFile(moduleId, {
51
+ const file = await fs.readFile(moduleId, {
52
52
  encoding: 'utf-8'
53
53
  });
54
54
  return `export default ${JSON.stringify(file)}`;
@@ -75,7 +75,7 @@ function staticAssets({
75
75
  return cached;
76
76
  }
77
77
  const file = cleanModuleIdentifier(id);
78
- const content = await promises.readFile(file);
78
+ const content = await fs.readFile(file);
79
79
  let url;
80
80
  if (!file.endsWith('.svg') && content.length < inlineLimit) {
81
81
  // base64 inlined as a string
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ const CSS_REGEX = /\.css$/;
4
+ const CSS_MODULE_REGEX = /\.module\.css$/;
5
+ function css({
6
+ minify = true,
7
+ emit = true
8
+ }) {
9
+ const styles = new Map();
10
+ return {
11
+ name: '@quilted/css',
12
+ async transform(code, id) {
13
+ if (!CSS_REGEX.test(id)) return;
14
+ const {
15
+ transform
16
+ } = await import('lightningcss');
17
+ const transformed = transform({
18
+ filename: id,
19
+ code: new TextEncoder().encode(code),
20
+ cssModules: CSS_MODULE_REGEX.test(id),
21
+ minify: emit && minify
22
+ });
23
+ styles.set(id, new TextDecoder().decode(transformed.code));
24
+ const exports = transformed.exports ? Object.fromEntries(Object.entries(transformed.exports).map(([key, exported]) => [key, exported.name])) : undefined;
25
+ return {
26
+ code: exports ? `export default JSON.parse(${JSON.stringify(JSON.stringify(exports))})` : `export default undefined;`,
27
+ map: {
28
+ mappings: ''
29
+ },
30
+ moduleSideEffects: 'no-treeshake'
31
+ };
32
+ },
33
+ async renderChunk(_, chunk) {
34
+ if (!emit) return null;
35
+ let chunkCss = '';
36
+ for (const id of Object.keys(chunk.modules)) {
37
+ if (CSS_REGEX.test(id) && styles.has(id)) {
38
+ chunkCss += styles.get(id);
39
+ }
40
+ }
41
+ if (chunkCss.length === 0) return null;
42
+ const code = chunkCss;
43
+
44
+ // if (minify) {
45
+ // const {default: CleanCSS} = await import('clean-css');
46
+
47
+ // const cleaner = new CleanCSS({
48
+ // rebase: false,
49
+ // });
50
+
51
+ // const minified = cleaner.minify(chunkCss);
52
+
53
+ // if (minified.errors.length > 0) {
54
+ // throw minified.errors[0];
55
+ // }
56
+
57
+ // code = minified.styles;
58
+ // }
59
+
60
+ const fileHandle = this.emitFile({
61
+ type: 'asset',
62
+ name: `${chunk.fileName.split('.')[0]}.css`,
63
+ source: code
64
+ });
65
+ chunk.imports.push(this.getFileName(fileHandle));
66
+ return null;
67
+ }
68
+ };
69
+ }
70
+
71
+ exports.css = css;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var path = require('node:path');
4
- var promises = require('node:fs/promises');
4
+ var fs = require('node:fs/promises');
5
5
  var graphql$1 = require('graphql');
6
6
  var transform = require('./graphql/transform.cjs');
7
7
 
@@ -46,10 +46,10 @@ function graphql({
46
46
  operations[operation.id] = operation.source;
47
47
  }
48
48
  }
49
- await promises.mkdir(path.dirname(manifestPath), {
49
+ await fs.mkdir(path.dirname(manifestPath), {
50
50
  recursive: true
51
51
  });
52
- await promises.writeFile(manifestPath, JSON.stringify(operations, null, 2));
52
+ await fs.writeFile(manifestPath, JSON.stringify(operations, null, 2));
53
53
  }
54
54
  };
55
55
  }
@@ -71,7 +71,7 @@ async function loadDocument(code, file, plugin, add, level = 0, seen = new Set()
71
71
  throw new Error(`Could not find ${JSON.stringify(imported)} from ${JSON.stringify(file)}`);
72
72
  }
73
73
  plugin.addWatchFile(resolvedId.id);
74
- const contents = await promises.readFile(resolvedId.id, {
74
+ const contents = await fs.readFile(resolvedId.id, {
75
75
  encoding: 'utf8'
76
76
  });
77
77
  return loadDocument(contents, resolvedId.id, plugin, add, level + 1, seen);
@@ -9,6 +9,7 @@ function sourceCode({
9
9
  targets
10
10
  }) {
11
11
  return babel({
12
+ envName: mode,
12
13
  configFile: false,
13
14
  babelrc: false,
14
15
  presets: [require$1.resolve('@babel/preset-typescript'), [require$1.resolve('@babel/preset-react'), {
@@ -29,11 +30,14 @@ function sourceCode({
29
30
  plugins: [[require$1.resolve('@babel/plugin-proposal-decorators'), {
30
31
  version: '2023-01'
31
32
  }]],
32
- targets,
33
33
  extensions: ['.ts', '.tsx', '.mts', '.mtsx', '.js', '.jsx', '.es6', '.es', '.mjs'],
34
34
  exclude: 'node_modules/**',
35
35
  babelHelpers: 'bundled',
36
- skipPreflightCheck: true
36
+ skipPreflightCheck: true,
37
+ // Babel doesn’t like this option being set to `undefined`.
38
+ ...(targets ? {
39
+ targets
40
+ } : {})
37
41
  });
38
42
  }
39
43
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var promises = require('node:fs/promises');
3
+ var fs = require('node:fs/promises');
4
4
  var node_module = require('node:module');
5
5
 
6
6
  function systemJS({
@@ -19,7 +19,7 @@ function systemJS({
19
19
  const fileHandle = this.emitFile({
20
20
  type: 'asset',
21
21
  name: 'loader.js',
22
- source: (await promises.readFile(systemjs, {
22
+ source: (await fs.readFile(systemjs, {
23
23
  encoding: 'utf8'
24
24
  })).replace(
25
25
  // Remove the source map comment, if it is present, because we don’t upload the
package/build/esm/app.mjs CHANGED
@@ -13,20 +13,33 @@ async function quiltAppBrowser({
13
13
  graphql = true
14
14
  } = {}) {
15
15
  const mode = (typeof env === 'object' ? env?.mode : undefined) ?? 'production';
16
- const minify = assets?.minify ?? true;
16
+ const minify = assets?.minify ?? mode === 'production';
17
+ const baseURL = assets?.baseURL ?? '/assets/';
17
18
  const [{
18
19
  visualizer
20
+ }, {
21
+ assetManifest
19
22
  }, {
20
23
  sourceCode
24
+ }, {
25
+ css
21
26
  }, {
22
27
  rawAssets,
23
28
  staticAssets
24
29
  }, {
25
30
  systemJS
26
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/source-code.mjs'), import('./features/assets.mjs'), import('./features/system-js.mjs'), getNodePlugins()]);
27
- const plugins = [...nodePlugins, systemJS(), sourceCode({
31
+ }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('@quilted/assets/rollup'), import('./features/source-code.mjs'), import('./features/css.mjs'), import('./features/assets.mjs'), import('./features/system-js.mjs'), getNodePlugins()]);
32
+ const plugins = [...nodePlugins, systemJS({
33
+ minify
34
+ }), sourceCode({
28
35
  mode
29
- }), rawAssets(), staticAssets()];
36
+ }), css({
37
+ minify,
38
+ emit: true
39
+ }), rawAssets(), staticAssets({
40
+ baseURL,
41
+ emit: true
42
+ })];
30
43
  if (env) {
31
44
  const {
32
45
  magicModuleEnv,
@@ -68,15 +81,28 @@ async function quiltAppBrowser({
68
81
  } = await import('rollup-plugin-esbuild');
69
82
  plugins.push(minify());
70
83
  }
71
- plugins.push(visualizer({
84
+ plugins.push(
85
+ // @ts-expect-error The plugin still depends on Rollup 3
86
+ assetManifest({
87
+ baseUrl: baseURL,
88
+ path: path.resolve(`build/manifests/assets.json`)
89
+ }), visualizer({
72
90
  template: 'treemap',
73
91
  open: false,
74
92
  brotliSize: true,
75
- filename: path.resolve(`reports/bundle-visualizer.html`)
93
+ filename: path.resolve(`build/reports/bundle-visualizer.html`)
76
94
  }));
77
95
  return {
78
96
  input: entry,
79
97
  plugins,
98
+ onwarn(warning, defaultWarn) {
99
+ // Removes annoying warnings for React-focused libraries that
100
+ // include 'use client' directives.
101
+ if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && /['"]use client['"]/.test(warning.message)) {
102
+ return;
103
+ }
104
+ defaultWarn(warning);
105
+ },
80
106
  output: {
81
107
  // format: isESM ? 'esm' : 'systemjs',
82
108
  format: 'esm',
@@ -91,7 +117,7 @@ async function quiltAppBrowser({
91
117
  async function quiltAppServer({
92
118
  app,
93
119
  env,
94
- graphql,
120
+ graphql = true,
95
121
  entry = MAGIC_MODULE_ENTRY,
96
122
  minify = false
97
123
  } = {}) {
@@ -100,14 +126,19 @@ async function quiltAppServer({
100
126
  visualizer
101
127
  }, {
102
128
  sourceCode
129
+ }, {
130
+ css
103
131
  }, {
104
132
  rawAssets,
105
133
  staticAssets
106
134
  }, {
107
135
  magicModuleRequestRouterEntry
108
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/source-code.mjs'), import('./features/assets.mjs'), import('./features/request-router.mjs'), getNodePlugins()]);
136
+ }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/source-code.mjs'), import('./features/css.mjs'), import('./features/assets.mjs'), import('./features/request-router.mjs'), getNodePlugins()]);
109
137
  const plugins = [...nodePlugins, sourceCode({
110
138
  mode
139
+ }), css({
140
+ emit: false,
141
+ minify
111
142
  }), rawAssets(), staticAssets({
112
143
  emit: false
113
144
  })];
@@ -159,7 +190,7 @@ async function quiltAppServer({
159
190
  template: 'treemap',
160
191
  open: false,
161
192
  brotliSize: true,
162
- filename: path.resolve(`reports/bundle-visualizer.html`)
193
+ filename: path.resolve(`build/reports/bundle-visualizer.html`)
163
194
  }));
164
195
  return {
165
196
  input: entry,
@@ -0,0 +1,69 @@
1
+ const CSS_REGEX = /\.css$/;
2
+ const CSS_MODULE_REGEX = /\.module\.css$/;
3
+ function css({
4
+ minify = true,
5
+ emit = true
6
+ }) {
7
+ const styles = new Map();
8
+ return {
9
+ name: '@quilted/css',
10
+ async transform(code, id) {
11
+ if (!CSS_REGEX.test(id)) return;
12
+ const {
13
+ transform
14
+ } = await import('lightningcss');
15
+ const transformed = transform({
16
+ filename: id,
17
+ code: new TextEncoder().encode(code),
18
+ cssModules: CSS_MODULE_REGEX.test(id),
19
+ minify: emit && minify
20
+ });
21
+ styles.set(id, new TextDecoder().decode(transformed.code));
22
+ const exports = transformed.exports ? Object.fromEntries(Object.entries(transformed.exports).map(([key, exported]) => [key, exported.name])) : undefined;
23
+ return {
24
+ code: exports ? `export default JSON.parse(${JSON.stringify(JSON.stringify(exports))})` : `export default undefined;`,
25
+ map: {
26
+ mappings: ''
27
+ },
28
+ moduleSideEffects: 'no-treeshake'
29
+ };
30
+ },
31
+ async renderChunk(_, chunk) {
32
+ if (!emit) return null;
33
+ let chunkCss = '';
34
+ for (const id of Object.keys(chunk.modules)) {
35
+ if (CSS_REGEX.test(id) && styles.has(id)) {
36
+ chunkCss += styles.get(id);
37
+ }
38
+ }
39
+ if (chunkCss.length === 0) return null;
40
+ const code = chunkCss;
41
+
42
+ // if (minify) {
43
+ // const {default: CleanCSS} = await import('clean-css');
44
+
45
+ // const cleaner = new CleanCSS({
46
+ // rebase: false,
47
+ // });
48
+
49
+ // const minified = cleaner.minify(chunkCss);
50
+
51
+ // if (minified.errors.length > 0) {
52
+ // throw minified.errors[0];
53
+ // }
54
+
55
+ // code = minified.styles;
56
+ // }
57
+
58
+ const fileHandle = this.emitFile({
59
+ type: 'asset',
60
+ name: `${chunk.fileName.split('.')[0]}.css`,
61
+ source: code
62
+ });
63
+ chunk.imports.push(this.getFileName(fileHandle));
64
+ return null;
65
+ }
66
+ };
67
+ }
68
+
69
+ export { css };
@@ -7,6 +7,7 @@ function sourceCode({
7
7
  targets
8
8
  }) {
9
9
  return babel({
10
+ envName: mode,
10
11
  configFile: false,
11
12
  babelrc: false,
12
13
  presets: [require.resolve('@babel/preset-typescript'), [require.resolve('@babel/preset-react'), {
@@ -27,11 +28,14 @@ function sourceCode({
27
28
  plugins: [[require.resolve('@babel/plugin-proposal-decorators'), {
28
29
  version: '2023-01'
29
30
  }]],
30
- targets,
31
31
  extensions: ['.ts', '.tsx', '.mts', '.mtsx', '.js', '.jsx', '.es6', '.es', '.mjs'],
32
32
  exclude: 'node_modules/**',
33
33
  babelHelpers: 'bundled',
34
- skipPreflightCheck: true
34
+ skipPreflightCheck: true,
35
+ // Babel doesn’t like this option being set to `undefined`.
36
+ ...(targets ? {
37
+ targets
38
+ } : {})
35
39
  });
36
40
  }
37
41
 
@@ -13,20 +13,33 @@ async function quiltAppBrowser({
13
13
  graphql = true
14
14
  } = {}) {
15
15
  const mode = (typeof env === 'object' ? env?.mode : undefined) ?? 'production';
16
- const minify = assets?.minify ?? true;
16
+ const minify = assets?.minify ?? mode === 'production';
17
+ const baseURL = assets?.baseURL ?? '/assets/';
17
18
  const [{
18
19
  visualizer
20
+ }, {
21
+ assetManifest
19
22
  }, {
20
23
  sourceCode
24
+ }, {
25
+ css
21
26
  }, {
22
27
  rawAssets,
23
28
  staticAssets
24
29
  }, {
25
30
  systemJS
26
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/source-code.esnext'), import('./features/assets.esnext'), import('./features/system-js.esnext'), getNodePlugins()]);
27
- const plugins = [...nodePlugins, systemJS(), sourceCode({
31
+ }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('@quilted/assets/rollup'), import('./features/source-code.esnext'), import('./features/css.esnext'), import('./features/assets.esnext'), import('./features/system-js.esnext'), getNodePlugins()]);
32
+ const plugins = [...nodePlugins, systemJS({
33
+ minify
34
+ }), sourceCode({
28
35
  mode
29
- }), rawAssets(), staticAssets()];
36
+ }), css({
37
+ minify,
38
+ emit: true
39
+ }), rawAssets(), staticAssets({
40
+ baseURL,
41
+ emit: true
42
+ })];
30
43
  if (env) {
31
44
  const {
32
45
  magicModuleEnv,
@@ -68,15 +81,28 @@ async function quiltAppBrowser({
68
81
  } = await import('rollup-plugin-esbuild');
69
82
  plugins.push(minify());
70
83
  }
71
- plugins.push(visualizer({
84
+ plugins.push(
85
+ // @ts-expect-error The plugin still depends on Rollup 3
86
+ assetManifest({
87
+ baseUrl: baseURL,
88
+ path: path.resolve(`build/manifests/assets.json`)
89
+ }), visualizer({
72
90
  template: 'treemap',
73
91
  open: false,
74
92
  brotliSize: true,
75
- filename: path.resolve(`reports/bundle-visualizer.html`)
93
+ filename: path.resolve(`build/reports/bundle-visualizer.html`)
76
94
  }));
77
95
  return {
78
96
  input: entry,
79
97
  plugins,
98
+ onwarn(warning, defaultWarn) {
99
+ // Removes annoying warnings for React-focused libraries that
100
+ // include 'use client' directives.
101
+ if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && /['"]use client['"]/.test(warning.message)) {
102
+ return;
103
+ }
104
+ defaultWarn(warning);
105
+ },
80
106
  output: {
81
107
  // format: isESM ? 'esm' : 'systemjs',
82
108
  format: 'esm',
@@ -91,7 +117,7 @@ async function quiltAppBrowser({
91
117
  async function quiltAppServer({
92
118
  app,
93
119
  env,
94
- graphql,
120
+ graphql = true,
95
121
  entry = MAGIC_MODULE_ENTRY,
96
122
  minify = false
97
123
  } = {}) {
@@ -100,14 +126,19 @@ async function quiltAppServer({
100
126
  visualizer
101
127
  }, {
102
128
  sourceCode
129
+ }, {
130
+ css
103
131
  }, {
104
132
  rawAssets,
105
133
  staticAssets
106
134
  }, {
107
135
  magicModuleRequestRouterEntry
108
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/source-code.esnext'), import('./features/assets.esnext'), import('./features/request-router.esnext'), getNodePlugins()]);
136
+ }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/source-code.esnext'), import('./features/css.esnext'), import('./features/assets.esnext'), import('./features/request-router.esnext'), getNodePlugins()]);
109
137
  const plugins = [...nodePlugins, sourceCode({
110
138
  mode
139
+ }), css({
140
+ emit: false,
141
+ minify
111
142
  }), rawAssets(), staticAssets({
112
143
  emit: false
113
144
  })];
@@ -159,7 +190,7 @@ async function quiltAppServer({
159
190
  template: 'treemap',
160
191
  open: false,
161
192
  brotliSize: true,
162
- filename: path.resolve(`reports/bundle-visualizer.html`)
193
+ filename: path.resolve(`build/reports/bundle-visualizer.html`)
163
194
  }));
164
195
  return {
165
196
  input: entry,
@@ -0,0 +1,69 @@
1
+ const CSS_REGEX = /\.css$/;
2
+ const CSS_MODULE_REGEX = /\.module\.css$/;
3
+ function css({
4
+ minify = true,
5
+ emit = true
6
+ }) {
7
+ const styles = new Map();
8
+ return {
9
+ name: '@quilted/css',
10
+ async transform(code, id) {
11
+ if (!CSS_REGEX.test(id)) return;
12
+ const {
13
+ transform
14
+ } = await import('lightningcss');
15
+ const transformed = transform({
16
+ filename: id,
17
+ code: new TextEncoder().encode(code),
18
+ cssModules: CSS_MODULE_REGEX.test(id),
19
+ minify: emit && minify
20
+ });
21
+ styles.set(id, new TextDecoder().decode(transformed.code));
22
+ const exports = transformed.exports ? Object.fromEntries(Object.entries(transformed.exports).map(([key, exported]) => [key, exported.name])) : undefined;
23
+ return {
24
+ code: exports ? `export default JSON.parse(${JSON.stringify(JSON.stringify(exports))})` : `export default undefined;`,
25
+ map: {
26
+ mappings: ''
27
+ },
28
+ moduleSideEffects: 'no-treeshake'
29
+ };
30
+ },
31
+ async renderChunk(_, chunk) {
32
+ if (!emit) return null;
33
+ let chunkCss = '';
34
+ for (const id of Object.keys(chunk.modules)) {
35
+ if (CSS_REGEX.test(id) && styles.has(id)) {
36
+ chunkCss += styles.get(id);
37
+ }
38
+ }
39
+ if (chunkCss.length === 0) return null;
40
+ const code = chunkCss;
41
+
42
+ // if (minify) {
43
+ // const {default: CleanCSS} = await import('clean-css');
44
+
45
+ // const cleaner = new CleanCSS({
46
+ // rebase: false,
47
+ // });
48
+
49
+ // const minified = cleaner.minify(chunkCss);
50
+
51
+ // if (minified.errors.length > 0) {
52
+ // throw minified.errors[0];
53
+ // }
54
+
55
+ // code = minified.styles;
56
+ // }
57
+
58
+ const fileHandle = this.emitFile({
59
+ type: 'asset',
60
+ name: `${chunk.fileName.split('.')[0]}.css`,
61
+ source: code
62
+ });
63
+ chunk.imports.push(this.getFileName(fileHandle));
64
+ return null;
65
+ }
66
+ };
67
+ }
68
+
69
+ export { css };