Rspack 的 Loader 系统是如何工作的?
Rspack 的 Loader 系统是其处理各种文件类型的核心机制,虽然基于 Rust 开发,但设计上充分考虑了与 Webpack Loader 生态的兼容性。以下是 Rspack Loader 系统的详细说明:Loader 基本概念Loader 是一种文件转换器,用于将源文件转换为 Rspack 可以处理的模块。Loader 可以:转换文件类型(如 TypeScript 转 JavaScript)处理资源文件(如图片、字体)执行代码转换(如 Babel 转译)应用代码检查(如 ESLint)Loader 配置方式基本配置module.exports = { module: { rules: [ { test: /\.js$/, use: 'babel-loader' } ] }}多个 Loadermodule.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader', 'postcss-loader' ] } ] }}Loader 选项module.exports = { module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }}常用 Loader1. Babel Loader用于转译 ES6+ 代码:module.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处理 CSS 文件:module.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: false, sourceMap: true } } ] } ] }}3. File Loader处理文件资源:module.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/i, type: 'asset/resource', generator: { filename: 'images/[hash][ext][query]' } } ] }}4. URL Loader内联小文件:module.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/i, type: 'asset', parser: { dataUrlCondition: { maxSize: 8192 } } } ] }}内置 LoaderRspack 提供了一些内置的 Loader:1. builtin:swc-loader超快的 JavaScript/TypeScript 编译器:module.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内置的 CSS Loader:module.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'builtin:css-loader' ] } ] }}Loader 执行顺序Loader 从右到左、从下到上执行:module.exports = { module: { rules: [ { test: /\.scss$/, use: [ 'style-loader', // 3. 将 CSS 注入到 DOM 'css-loader', // 2. 解析 CSS 'sass-loader' // 1. 编译 SCSS ] } ] }}Loader 匹配规则1. test使用正则表达式匹配文件:{ test: /\.js$/, use: 'babel-loader'}2. include只包含特定目录:{ test: /\.js$/, include: path.resolve(__dirname, 'src'), use: 'babel-loader'}3. exclude排除特定目录:{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader'}4. oneOf只匹配第一个规则:{ test: /\.css$/, oneOf: [ { resourceQuery: /module/, use: 'css-loader?modules' }, { use: 'css-loader' } ]}Loader 条件1. resource匹配资源路径:{ test: /\.js$/, resource: { and: [/src/, /test/], not: [/node_modules/], or: [/\.js$/, /\.jsx$/] }}2. issuer匹配导入者:{ test: /\.css$/, issuer: /\.js$/, use: 'style-loader'}Loader 性能优化1. 缓存{ test: /\.js$/, use: { loader: 'babel-loader', options: { cacheDirectory: true } }}2. 排除不必要的文件{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader'}3. 并行处理{ test: /\.js$/, use: { loader: 'thread-loader', options: { workers: 4 } }}自定义 Loader基本结构module.exports = function(source) { // 处理源代码 const result = source.replace(/foo/g, 'bar'); // 返回转换后的代码 return result;};同步 Loadermodule.exports = function(content) { return content.toUpperCase();};异步 Loadermodule.exports = function(content) { const callback = this.async(); setTimeout(() => { callback(null, content.toUpperCase()); }, 100);};带 options 的 Loadermodule.exports = function(content, map, meta) { const options = this.getOptions(); // 使用 options const result = content.replace(options.search, options.replace); return result;};Loader 最佳实践合理使用 Loader:只在需要时使用 Loader避免过度使用 Loader选择合适的 Loader性能优化:使用缓存提升性能排除不必要的文件合理配置 Loader 选项代码质量:编写可测试的 Loader提供清晰的文档处理错误情况兼容性:确保 Loader 兼容性测试不同环境提供降级方案Rspack 的 Loader 系统为开发者提供了强大的文件处理能力,通过合理配置和使用 Loader,可以处理各种类型的文件,满足不同的构建需求。