Azure流水线中Webpack+React项目npm run build失败:无法解析Scss/CSS文件
微前端应用Azure流水线构建失败:无法解析CSS文件
问题概述
本地环境下npm run build执行正常,但Azure流水线构建时出现错误,提示无法找到./css/index.css和./css/style.scss文件,多次调整webpack输出路径未解决问题。
错误信息
+ CI= npm run build > mcmp-core-ui@1.0.0 build > webpack --config webpack/webpack.prod.js assets by status 160 KiB [cached] 7 assets runtime modules 6.78 KiB 11 modules orphan modules 2.81 KiB [orphan] 6 modules cacheable modules 146 KiB (javascript) 13.1 KiB (asset) modules by path ./node_modules/ 145 KiB modules by path ./node_modules/react/ 8 KiB 4 modules modules by path ./node_modules/react-dom/ 131 KiB 3 modules modules by path ./node_modules/scheduler/ 4.33 KiB ./node_modules/scheduler/index.js 198 bytes [built] [code generated] ./node_modules/scheduler/cjs/scheduler.production.min.js 4.14 KiB [built] [code generated] ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js + 5 modules 2.12 KiB [built] [code generated] modules by path ./src/ 1.51 KiB (javascript) 13.1 KiB (asset) ./src/index.tsx 33 bytes [built] [code generated] ./src/bootstrap.tsx + 2 modules 1.44 KiB [built] [code generated] ./src/assets/images/user.png 42 bytes (javascript) 13.1 KiB (asset) [built] [code generated] **ERROR in ./src/App.tsx 3:0-25** ***Module not found: Error: Can't resolve './css/index.css' in '/opt/atlassian/pipelines/agent/build/src' resolve './css/index.css' in '/opt/atlassian/pipelines/agent/build/src' using description file: /opt/atlassian/pipelines/agent/build/package.json (relative path: ./src)*** ***Field 'browser' doesn't contain a valid alias configuration using description file: /opt/atlassian/pipelines/agent/build/package.json (relative path: ./src/css/index.css) no extension Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/index.css doesn't exist .tsx*** Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/index.css.tsx doesn't exist .ts Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/index.css.ts doesn't exist .js Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/index.css.js doesn't exist .json Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/index.css.json doesn't exist as directory /opt/atlassian/pipelines/agent/build/src/css/index.css doesn't exist @ ./src/bootstrap.tsx 3:0-24 7:30-33 @ ./src/index.tsx ERROR in ./src/App.tsx 4:0-26 Module not found: Error: Can't resolve './css/style.scss' in '/opt/atlassian/pipelines/agent/build/src' resolve './css/style.scss' in '/opt/atlassian/pipelines/agent/build/src' using description file: /opt/atlassian/pipelines/agent/build/package.json (relative path: ./src) Field 'browser' doesn't contain a valid alias configuration using description file: /opt/atlassian/pipelines/agent/build/package.json (relative path: ./src/css/style.scss) no extension Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/style.scss doesn't exist .tsx Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/style.scss.tsx doesn't exist .ts Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/style.scss.ts doesn't exist .js Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/style.scss.js doesn't exist .json Field 'browser' doesn't contain a valid alias configuration /opt/atlassian/pipelines/agent/build/src/css/style.scss.json doesn't exist as directory /opt/atlassian/pipelines/agent/build/src/css/style.scss doesn't exist @ ./src/bootstrap.tsx 3:0-24 7:30-33 @ ./src/index.tsx
项目文件结构
node_modules public index.html src /css/ - index.css - style.scss App.tsx bootstrap.tsx index.tsx webpack webpack.common.js webpack.dev.js webpack.prod.js package.json
关键配置
package.json 脚本
"scripts": { "start": "webpack serve --config webpack/webpack.dev.js", "build": "webpack --config webpack/webpack.prod.js", "lint": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx,json}\"", "format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"" },
webpack.common.js 核心配置
module.exports = { name: 'mcmp', entry: path.resolve(__dirname, '..', './src/index.tsx'), resolve: { extensions: ['.tsx', '.ts', '.js', '.json'], mainFields: ['source', 'module', 'main'], modules: [path.join(__dirname, '../node_modules')], }, module: { rules: [ { test: /\.(?:js|ts|tsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', } }, { test: /\.(?:css|scss)$/, include: path.resolve(__dirname, '..', 'src'), use: [ // Creates `style` nodes from JS strings "style-loader", // Translates CSS into CommonJS "css-loader", // Compiles Sass to CSS "sass-loader", "postcss-loader", ], }, { test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: 'asset/resource', }, { test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: 'asset/inline', }, ] }, output: { path: path.resolve(__dirname, '..', './build'), filename: '[name]_[fullhash].js', }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: path.resolve(__dirname, '..', './public/index.html'), favicon: path.resolve(__dirname, '..', './public/images/favicon.ico'), showErrors: true, }), new MiniCssExtractPlugin({ filename: '[name]_[fullhash].css', chunkFilename: '[id].css', }), new WebpackManifestPlugin({ writeToFileEmit: true, }), new ForkTsCheckerWebpackPlugin(), ], }
webpack.prod.js 生产配置
const webpack = require('webpack'); const { merge } = require('webpack-merge'); const commonConfig = require('./webpack.common'); const Dotenv = require('dotenv-webpack'); const path = require('path'); const prodConfg = { mode: 'production', devtool: 'source-map', plugins: [ new Dotenv({ path: path.resolve(__dirname, '..', './env/prod.env'), }), ], } module.exports = merge(commonConfig, prodConfg);
App.tsx 引入方式
import { useState } from 'react' import './css/index.css' import './css/style.scss' import UserImage from './assets/images/user.png' const App = () => { const [count, setCount] = useState(0) return ( <div> <h2>App</h2> <p>ENVIRONMENT VARIABLE: {process.env.REACT_APP_NAME}</p> <p> <img src={UserImage} alt=" of user" title=" of user" width={200} /> </p> <p> <button onClick={() => setCount(count + 1)}>Click</button> </p> <p>COUNT: {count} </p> </div> ) } export default App
解决方案
1. 修复webpack解析扩展名配置
当前resolve.extensions未包含.css和.scss,导致webpack无法识别这类文件的扩展名,修改webpack.common.js的resolve配置:
resolve: { extensions: ['.tsx', '.ts', '.js', '.json', '.css', '.scss'], // 添加.css和.scss扩展名 mainFields: ['source', 'module', 'main'], modules: [path.join(__dirname, '../node_modules')], },
2. 生产环境替换style-loader
生产环境下已配置MiniCssExtractPlugin,但仍使用style-loader会导致冲突,在webpack.prod.js中覆盖CSS规则:
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 顶部引入插件 const prodConfg = { mode: 'production', devtool: 'source-map', module: { rules: [ { test: /\.(?:css|scss)$/, include: path.resolve(__dirname, '..', 'src'), use: [ MiniCssExtractPlugin.loader, // 替换style-loader "css-loader", "sass-loader", "postcss-loader", ], }, ] }, plugins: [ new Dotenv({ path: path.resolve(__dirname, '..', './env/prod.env'), }), ], }
3. 检查流水线文件检出配置
确认Azure流水线的checkout步骤未忽略src/css目录,同时检查.gitignore是否意外排除了CSS/SCSS文件,确保所有静态资源都能被正确检出到构建环境。
4. 核对文件名大小写
Azure流水线通常运行在Linux环境,区分文件名大小写,检查App.tsx中的引入路径(如./css/index.css)与实际文件的大小写是否完全一致,避免因大小写不匹配导致文件找不到。
5. 确认流水线工作目录
错误中显示构建路径为/opt/atlassian/pipelines/agent/build/src,确认流水线的工作目录配置与本地一致,避免路径解析错误。
内容的提问来源于stack exchange,提问作者Noventiq
相关产品推荐
相关产品推荐

