|
| 1 | +# Layer |
| 2 | + |
| 3 | +Layer is a powerful feature provided by Rspack that allows you to categorize and manage modules. By assigning different layers to modules, you can perform differentiated processing for different types of modules, such as: |
| 4 | + |
| 5 | +- Using different compilation targets based on different layers |
| 6 | +- Splitting modules from different layers into different output directories |
| 7 | +- Applying different compilation strategies for code in different environments (such as server-side and client-side) |
| 8 | + |
| 9 | +## Ways to specify layers |
| 10 | + |
| 11 | +When a module is assigned a layer, all its dependent modules will also be assigned to that layer. For example, if you specify the layer as `client` for the root module, all modules starting from the root module and their dependencies will be assigned to the `client` layer. |
| 12 | + |
| 13 | +## Ways to specify layers |
| 14 | + |
| 15 | +You can specify layers for modules in the following ways: |
| 16 | + |
| 17 | +### 1. Specify via entry |
| 18 | + |
| 19 | +Directly specify layers for different entry points in the [entry configuration using the `layer`](/config/entry#entrydescriptionlayer) option: |
| 20 | + |
| 21 | +```js title="rspack.config.mjs" |
| 22 | +export default { |
| 23 | + entry: { |
| 24 | + server: { |
| 25 | + import: './src/server.js', |
| 26 | + layer: 'server', |
| 27 | + }, |
| 28 | + client: { |
| 29 | + import: './src/client.js', |
| 30 | + layer: 'client', |
| 31 | + }, |
| 32 | + }, |
| 33 | +}; |
| 34 | +``` |
| 35 | + |
| 36 | +### 2. Specify via loader rules |
| 37 | + |
| 38 | +You can use the [`rule.layer`](/config/module#rulelayer) option to specify a layer for all modules that match the rule: |
| 39 | + |
| 40 | +```js title="rspack.config.mjs" |
| 41 | +export default { |
| 42 | + module: { |
| 43 | + rules: [ |
| 44 | + { |
| 45 | + test: /\.js$/, |
| 46 | + layer: 'yourLayer', |
| 47 | + }, |
| 48 | + ], |
| 49 | + }, |
| 50 | +}; |
| 51 | +``` |
| 52 | + |
| 53 | +The layer assigned by [`rule.layer`](/config/module#rulelayer) will override the module's own layer. For example, if a module has been assigned a layer through Entry configuration, the layer assigned through Rule will override the layer specified by Entry. |
| 54 | + |
| 55 | +## Layer inheritance |
| 56 | + |
| 57 | +To better understand how Layer works, we categorize modules into two types: |
| 58 | + |
| 59 | +- **Regular modules**: Modules that are not explicitly assigned a layer |
| 60 | +- **Layer modules**: Modules that have been assigned a layer |
| 61 | + |
| 62 | +### Layer inheritance rules |
| 63 | + |
| 64 | +**1. Downward Inheritance** |
| 65 | + |
| 66 | +All dependent modules of a Layer module will inherit the same layer. For example, when you specify the layer as `'client'` for an entry module, all modules in the entire dependency tree starting from that entry will be assigned to the `'client'` layer. |
| 67 | + |
| 68 | +**2. Mid-path Override** |
| 69 | + |
| 70 | +If a module in the dependency chain is reassigned to a different layer (such as `'server'`) through Loader rules, then all subsequent dependencies starting from that module will follow the new layer. |
| 71 | + |
| 72 | +When a regular module is depended upon by multiple modules with different layers, that module will generate multiple copies in the build output, with each copy corresponding to a layer. |
| 73 | + |
| 74 | +**Example:** If both `'client'` layer and `'server'` layer depend on the same `lib.js` module, then: |
| 75 | + |
| 76 | +- The build output will contain two copies of `lib.js`: one belonging to the `'client'` layer and another to the `'server'` layer |
| 77 | +- The dependency modules of these two copies will also be duplicated and assigned according to the same rules |
| 78 | + |
| 79 | +## Applying different processing rules to different layers |
| 80 | + |
| 81 | +You can use [`issuerLayer`](/config/module#ruleissuerlayer) to filter modules from specific layers and apply different processing rules to them. The following example shows how to use different compilation targets for different layers: |
| 82 | + |
| 83 | +```js title="rspack.config.mjs" |
| 84 | +export default { |
| 85 | + module: { |
| 86 | + rules: [ |
| 87 | + { |
| 88 | + test: /\.js$/, |
| 89 | + oneOf: [ |
| 90 | + { |
| 91 | + issuerLayer: 'client', |
| 92 | + use: [ |
| 93 | + { |
| 94 | + loader: 'builtin:swc-loader', |
| 95 | + options: { |
| 96 | + jsc: { |
| 97 | + target: 'es5', |
| 98 | + }, |
| 99 | + }, |
| 100 | + }, |
| 101 | + ], |
| 102 | + }, |
| 103 | + { |
| 104 | + issuerLayer: 'server', |
| 105 | + use: [ |
| 106 | + { |
| 107 | + loader: 'builtin:swc-loader', |
| 108 | + options: { |
| 109 | + jsc: { |
| 110 | + target: 'es2020', |
| 111 | + }, |
| 112 | + }, |
| 113 | + }, |
| 114 | + ], |
| 115 | + }, |
| 116 | + ], |
| 117 | + }, |
| 118 | + ], |
| 119 | + }, |
| 120 | +}; |
| 121 | +``` |
| 122 | + |
| 123 | +## Layer-based code splitting |
| 124 | + |
| 125 | +During the build optimization phase, you can assign modules to different chunks based on different layers: |
| 126 | + |
| 127 | +```js title="rspack.config.mjs" |
| 128 | +export default { |
| 129 | + optimization: { |
| 130 | + splitChunks: { |
| 131 | + chunks: 'all', |
| 132 | + cacheGroups: { |
| 133 | + server: { |
| 134 | + layer: 'server', |
| 135 | + filename: 'server/[name].js', |
| 136 | + }, |
| 137 | + client: { |
| 138 | + layer: 'client', |
| 139 | + filename: 'client/[name].js', |
| 140 | + }, |
| 141 | + }, |
| 142 | + }, |
| 143 | + }, |
| 144 | +}; |
| 145 | +``` |
| 146 | + |
| 147 | +Through the above configuration, we successfully output server and client code to different directories respectively, achieving layer-based code separation. |
0 commit comments