Rspack's Loader system is the core mechanism for processing various file types. Although developed in Rust, its design fully considers compatibility with the Webpack Loader ecosystem. Here's a detailed explanation of Rspack's Loader system:
Basic Concepts of Loader
Loader is a file transformer used to convert source files into modules that Rspack can process. Loaders can:
- Convert file types (e.g., TypeScript to JavaScript)
- Process resource files (e.g., images, fonts)
- Execute code transformations (e.g., Babel transpilation)
- Apply code checking (e.g., ESLint)
Loader Configuration Methods
Basic Configuration
javascriptmodule.exports = { module: { rules: [ { test: /\.js$/, use: 'babel-loader' } ] } }
Multiple Loaders
javascriptmodule.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader', 'postcss-loader' ] } ] } }
Loader Options
javascriptmodule.exports = { module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] } }
Common Loaders
1. Babel Loader
For transpiling ES6+ code:
javascriptmodule.exports = { module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: ['@babel/plugin-transform-runtime'] } } } ] } }
2. CSS Loader
Process CSS files:
javascriptmodule.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: false, sourceMap: true } } ] } ] } }
3. File Loader
Process file resources:
javascriptmodule.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/i, type: 'asset/resource', generator: { filename: 'images/[hash][ext][query]' } } ] } }
4. URL Loader
Inline small files:
javascriptmodule.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/i, type: 'asset', parser: { dataUrlCondition: { maxSize: 8192 } } } ] } }
Built-in Loaders
Rspack provides some built-in Loaders:
1. builtin:swc-loader
Ultra-fast JavaScript/TypeScript compiler:
javascriptmodule.exports = { module: { rules: [ { test: /\.(js|jsx|ts|tsx)$/, use: { loader: 'builtin:swc-loader', options: { jsc: { parser: { syntax: 'typescript', tsx: true }, transform: { react: { runtime: 'automatic' } } } } } } ] } }
2. builtin:css-loader
Built-in CSS Loader:
javascriptmodule.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'builtin:css-loader' ] } ] } }
Loader Execution Order
Loaders execute from right to left, bottom to top:
javascriptmodule.exports = { module: { rules: [ { test: /\.scss$/, use: [ 'style-loader', // 3. Inject CSS into DOM 'css-loader', // 2. Parse CSS 'sass-loader' // 1. Compile SCSS ] } ] } }
Loader Matching Rules
1. test
Match files using regular expressions:
javascript{ test: /\.js$/, use: 'babel-loader' }
2. include
Only include specific directories:
javascript{ test: /\.js$/, include: path.resolve(__dirname, 'src'), use: 'babel-loader' }
3. exclude
Exclude specific directories:
javascript{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }
4. oneOf
Only match the first rule:
javascript{ test: /\.css$/, oneOf: [ { resourceQuery: /module/, use: 'css-loader?modules' }, { use: 'css-loader' } ] }
Loader Conditions
1. resource
Match resource path:
javascript{ test: /\.js$/, resource: { and: [/src/, /test/], not: [/node_modules/], or: [/\.js$/, /\.jsx$/] } }
2. issuer
Match importer:
javascript{ test: /\.css$/, issuer: /\.js$/, use: 'style-loader' }
Loader Performance Optimization
1. Caching
javascript{ test: /\.js$/, use: { loader: 'babel-loader', options: { cacheDirectory: true } } }
2. Exclude Unnecessary Files
javascript{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }
3. Parallel Processing
javascript{ test: /\.js$/, use: { loader: 'thread-loader', options: { workers: 4 } } }
Custom Loader
Basic Structure
javascriptmodule.exports = function(source) { // Process source code const result = source.replace(/foo/g, 'bar'); // Return transformed code return result; };
Synchronous Loader
javascriptmodule.exports = function(content) { return content.toUpperCase(); };
Asynchronous Loader
javascriptmodule.exports = function(content) { const callback = this.async(); setTimeout(() => { callback(null, content.toUpperCase()); }, 100); };
Loader with Options
javascriptmodule.exports = function(content, map, meta) { const options = this.getOptions(); // Use options const result = content.replace(options.search, options.replace); return result; };
Loader Best Practices
-
Reasonable Use of Loaders:
- Only use Loaders when necessary
- Avoid overusing Loaders
- Choose appropriate Loaders
-
Performance Optimization:
- Use caching to improve performance
- Exclude unnecessary files
- Reasonably configure Loader options
-
Code Quality:
- Write testable Loaders
- Provide clear documentation
- Handle error situations
-
Compatibility:
- Ensure Loader compatibility
- Test in different environments
- Provide fallback solutions
Rspack's Loader system provides developers with powerful file processing capabilities. Through reasonable configuration and use of Loaders, you can process various types of files to meet different build requirements.