shakapacker 9.0.0.beta.2 → 9.0.0.beta.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.
@@ -68,6 +68,13 @@ class Shakapacker::Configuration
68
68
  root_path.join(fetch(:public_root_path))
69
69
  end
70
70
 
71
+ def private_output_path
72
+ private_path = fetch(:private_output_path)
73
+ return nil unless private_path
74
+ validate_output_paths!
75
+ root_path.join(private_path)
76
+ end
77
+
71
78
  def public_output_path
72
79
  public_path.join(fetch(:public_output_path))
73
80
  end
@@ -149,6 +156,38 @@ class Shakapacker::Configuration
149
156
  end
150
157
 
151
158
  private
159
+ def validate_output_paths!
160
+ # Skip validation if already validated to avoid redundant checks
161
+ return if @validated_output_paths
162
+ @validated_output_paths = true
163
+
164
+ # Only validate when both paths are configured
165
+ return unless fetch(:private_output_path) && fetch(:public_output_path)
166
+
167
+ private_path_str, public_path_str = resolve_paths_for_comparison
168
+
169
+ if private_path_str == public_path_str
170
+ raise "Shakapacker configuration error: private_output_path and public_output_path must be different. " \
171
+ "Both paths resolve to '#{private_path_str}'. " \
172
+ "The private_output_path is for server-side bundles (e.g., SSR) that should not be served publicly."
173
+ end
174
+ end
175
+
176
+ def resolve_paths_for_comparison
177
+ private_full_path = root_path.join(fetch(:private_output_path))
178
+ public_full_path = root_path.join(fetch(:public_root_path), fetch(:public_output_path))
179
+
180
+ # Create directories if they don't exist (for testing)
181
+ private_full_path.mkpath unless private_full_path.exist?
182
+ public_full_path.mkpath unless public_full_path.exist?
183
+
184
+ # Use realpath to resolve symbolic links and relative paths
185
+ [private_full_path.realpath.to_s, public_full_path.realpath.to_s]
186
+ rescue Errno::ENOENT
187
+ # If paths don't exist yet, fall back to cleanpath for comparison
188
+ [private_full_path.cleanpath.to_s, public_full_path.cleanpath.to_s]
189
+ end
190
+
152
191
  def data
153
192
  @data ||= load
154
193
  end
@@ -1,4 +1,4 @@
1
1
  module Shakapacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "9.0.0.beta.2".freeze
3
+ VERSION = "9.0.0.beta.3".freeze
4
4
  end
data/package/index.d.ts CHANGED
@@ -9,6 +9,7 @@ declare module "shakapacker" {
9
9
  css_extract_ignore_order_warnings: boolean
10
10
  public_root_path: string
11
11
  public_output_path: string
12
+ private_output_path?: string
12
13
  cache_path: string
13
14
  webpack_compile_output: boolean
14
15
  shakapacker_precompile: boolean
@@ -23,6 +24,14 @@ declare module "shakapacker" {
23
24
  publicPath: string
24
25
  publicPathWithoutCDN: string
25
26
  manifestPath: string
27
+ manifest_path?: string
28
+ assets_bundler?: string
29
+ dev_server?: DevServerConfig
30
+ integrity?: {
31
+ enabled: boolean
32
+ cross_origin: string
33
+ hash_functions?: string[]
34
+ }
26
35
  }
27
36
 
28
37
  export interface Env {
@@ -60,6 +69,8 @@ declare module "shakapacker" {
60
69
  ipc?: boolean | string
61
70
  magic_html?: boolean
62
71
  live_reload?: boolean
72
+ inline_css?: boolean
73
+ env_prefix?: string
63
74
  open?:
64
75
  | boolean
65
76
  | string
@@ -136,4 +147,4 @@ declare module "shakapacker/package/babel/preset.js" {
136
147
  ) => TransformOptions & RequiredTransformOptions
137
148
 
138
149
  export = defaultConfigFunc
139
- }
150
+ }
@@ -12,6 +12,8 @@ debug("Adding JavaScript rule with builtin:swc-loader")
12
12
  rules.push({
13
13
  test: /\.(js|jsx|mjs)$/,
14
14
  exclude: /node_modules/,
15
+ // The 'type' field is required for Rspack to properly handle JavaScript modules
16
+ // when using builtin loaders. It ensures correct module parsing and transformation.
15
17
  type: "javascript/auto",
16
18
  use: [
17
19
  {
@@ -38,6 +40,8 @@ debug("Adding TypeScript rule with builtin:swc-loader")
38
40
  rules.push({
39
41
  test: /\.(ts|tsx)$/,
40
42
  exclude: /node_modules/,
43
+ // The 'type' field is required for Rspack to properly handle TypeScript modules
44
+ // when using builtin loaders. It ensures correct module parsing and transformation.
41
45
  type: "javascript/auto",
42
46
  use: [
43
47
  {
@@ -3,6 +3,7 @@ const { canProcess, moduleExists } = require("./helpers")
3
3
  const { requireOrError } = require("./requireOrError")
4
4
  const config = require("../config")
5
5
  const inliningCss = require("./inliningCss")
6
+ const { validateCssModulesConfig } = require("./validateCssModulesConfig")
6
7
 
7
8
  const getStyleRule = (test, preprocessors = []) => {
8
9
  if (moduleExists("css-loader")) {
@@ -19,17 +20,25 @@ const getStyleRule = (test, preprocessors = []) => {
19
20
  ? requireOrError("@rspack/core").CssExtractRspackPlugin.loader
20
21
  : requireOrError("mini-css-extract-plugin").loader
21
22
 
23
+ const cssLoaderOptions = {
24
+ sourceMap: true,
25
+ importLoaders: 2,
26
+ modules: {
27
+ auto: true,
28
+ // v9 defaults: named exports with camelCase conversion
29
+ namedExport: true,
30
+ exportLocalsConvention: "camelCase"
31
+ }
32
+ }
33
+
34
+ // Validate CSS modules configuration
35
+ validateCssModulesConfig(cssLoaderOptions)
36
+
22
37
  const use = [
23
38
  inliningCss ? "style-loader" : extractionPlugin,
24
39
  {
25
40
  loader: require.resolve("css-loader"),
26
- options: {
27
- sourceMap: true,
28
- importLoaders: 2,
29
- modules: {
30
- auto: true
31
- }
32
- }
41
+ options: cssLoaderOptions
33
42
  },
34
43
  tryPostcss(),
35
44
  ...preprocessors
@@ -0,0 +1,91 @@
1
+ /* eslint global-require: 0 */
2
+ const { warn } = require("./debug")
3
+
4
+ /**
5
+ * Validates CSS modules configuration and warns about potential issues
6
+ * with v9 defaults or conflicting settings.
7
+ */
8
+ const validateCssModulesConfig = (cssLoaderOptions) => {
9
+ // Skip validation in production by default for performance
10
+ if (
11
+ process.env.NODE_ENV === "production" &&
12
+ process.env.SHAKAPACKER_VALIDATE_CSS_MODULES !== "true"
13
+ ) {
14
+ return
15
+ }
16
+
17
+ if (!cssLoaderOptions || !cssLoaderOptions.modules) {
18
+ return
19
+ }
20
+
21
+ const { modules } = cssLoaderOptions
22
+
23
+ // Check for conflicting namedExport and esModule settings
24
+ if (modules.namedExport === true && modules.esModule === false) {
25
+ warn(
26
+ "⚠️ CSS Modules Configuration Warning:\n" +
27
+ " namedExport: true with esModule: false may cause issues.\n" +
28
+ " Consider setting esModule: true or removing it (defaults to true)."
29
+ )
30
+ }
31
+
32
+ // Check for v8-style configuration with v9
33
+ if (modules.namedExport === false) {
34
+ warn(
35
+ "ℹ️ CSS Modules Configuration Note:\n" +
36
+ " You are using namedExport: false (v8 behavior).\n" +
37
+ " Shakapacker v9 defaults to namedExport: true for better tree-shaking.\n" +
38
+ " See docs/css-modules-export-mode.md for migration instructions."
39
+ )
40
+ }
41
+
42
+ // Check for inconsistent exportLocalsConvention with namedExport
43
+ if (
44
+ modules.namedExport === true &&
45
+ modules.exportLocalsConvention === "asIs"
46
+ ) {
47
+ warn(
48
+ "⚠️ CSS Modules Configuration Warning:\n" +
49
+ " Using namedExport: true with exportLocalsConvention: 'asIs' may cause issues\n" +
50
+ " with kebab-case class names (e.g., 'my-button').\n" +
51
+ " Consider using exportLocalsConvention: 'camelCase' (v9 default)."
52
+ )
53
+ }
54
+
55
+ // Check for deprecated localIdentName pattern
56
+ if (
57
+ modules.localIdentName &&
58
+ modules.localIdentName.includes("[hash:base64]")
59
+ ) {
60
+ warn(
61
+ "⚠️ CSS Modules Configuration Warning:\n" +
62
+ " [hash:base64] is deprecated in css-loader v6+.\n" +
63
+ " Use [hash] instead for better compatibility."
64
+ )
65
+ }
66
+
67
+ // Check for potential TypeScript issues
68
+ if (
69
+ modules.namedExport === true &&
70
+ process.env.SHAKAPACKER_ASSET_COMPILER_TYPESCRIPT === "true"
71
+ ) {
72
+ warn(
73
+ "ℹ️ TypeScript CSS Modules Note:\n" +
74
+ " With namedExport: true, TypeScript projects should use:\n" +
75
+ " import * as styles from './styles.module.css'\n" +
76
+ " instead of: import styles from './styles.module.css'\n" +
77
+ " See docs/css-modules-export-mode.md for TypeScript setup."
78
+ )
79
+ }
80
+
81
+ // Check for auto: true with getLocalIdent (potential conflict)
82
+ if (modules.auto === true && modules.getLocalIdent) {
83
+ warn(
84
+ "⚠️ CSS Modules Configuration Warning:\n" +
85
+ " Using both 'auto: true' and 'getLocalIdent' may cause conflicts.\n" +
86
+ " The 'auto' option determines which files are treated as CSS modules."
87
+ )
88
+ }
89
+ }
90
+
91
+ module.exports = { validateCssModulesConfig }