如何将 sass 添加到 webpack + react?

How to add sass to webpack + react?

如何在配置 webpack + React 中正确添加 sass(in jsx import 'style.sass')?

var path = require('path');

var BUILD_DIR = path.resolve(__dirname, './');
var APP_DIR = path.resolve(__dirname, 'src/');

var config = {
    entry: APP_DIR + '/index.jsx',
    output: {
        path: BUILD_DIR,
        filename: 'bundle.js'
    },
    devServer: {
        contentBase: BUILD_DIR
    },
    module: {
        loaders: [
            {
                test: /\.jsx?/,
                include: APP_DIR,
                loader: 'babel-loader'
            }
        ]
        ,
        rules: [{
            test: /\.scss$/,
            use: [{
                loader: "style-loader" // creates style nodes from JS strings
            }, {
                loader: "css-loader" // translates CSS into CommonJS
            }, {
                loader: "sass-loader" // compiles Sass to CSS
            }]
        }]
    }
};

module.exports = config;

错误:

ERROR in ./src/index.jsx Module parse failed: C:\Users\steko\Desktop\TEST\m-react\src\index.jsx Unexpected token (9:8) You may need an appropriate loader to handle this file type. | render () { | return ( | | Hello React Project!!! |

git

在 webpack 的模块部分执行此操作

module: {
    rules: [
        {
            test: /\.jsx?/,
            loader: 'babel-loader',
            include: APP_DIR
        },
        {
            test: /\.scss$/,
            use: ExtractTextPlugin.extract({
                fallback: "style-loader",
                use: "css-loader!sass-loader",
            })
        }
    ]
}

然后在您的 webpack 代码的插件区域执行此操作

plugins: [
    new ExtractTextPlugin('style.css'),
]

你将需要这个包extract-text-webpack-plugin

如果您还有任何问题,请告诉我。

我上面的ExtractTextPlugin,用于将您的js代码和css代码提取到2个单独的文件中。这很好,但不确定这是否是您的意思。

这就是我在 webpack 构建中解析 sass 文件的方式。 我稍后可以决定是将 css 保留在我的 js 文件中还是提取它。

 loaders: [
        {
            test: /\.scss$/,
            loader: "style-loader!css-loader!sass-loader"
        }
 ]

加载程序从右到左应用,因此:

  • 正在解析 sass 文件
  • 然后应用 css 加载器
  • 最后是样式加载器

最后,您的 js 输出文件中的 css 代码可以使用了,就像您加载的任何其他 css 文件一样。

这可能会使它更加混乱,但我想向您发送一份我用于开发环境的文件副本,其中包括 SASS 和 React。你应该能够决定什么是需要的,什么是不需要的。

我已经排除了任何与工作直接相关的内容,例如在 devServer 设置中用于代理的 IP 地址,但除此之外它是完整的。

希望对您有所帮助!

const webpack           = require('webpack');
const path              = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const Paths = {
    dist:           path.resolve(__dirname, 'dist'),
    src:            path.resolve(__dirname, 'src'),
    indexFile:      path.resolve(__dirname, 'src/index.jsx'),
    nodeModulesDir: path.resolve(__dirname, 'node_modules'),
    sassFile:       path.resolve(__dirname, 'assets/css/main.scss')
};

const config = {
    devtool: '#source-map',
    entry: {
        main: ['react-hot-loader/patch', 'babel-polyfill', Paths.indexFile, Paths.sassFile],
    },
    output: {
        path: Paths.dist,
        filename: "[name].[hash].bundle.js",
        publicPath: "/"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude:  [Paths.nodeModulesDir],
                use:   [{
                    loader: 'babel-loader?cacheDirectory&cacheIdentifier='+ Math.random(),
                    options: {
                        presets: ["env", "react", "stage-0",
                            ["env", {
                                "targets": {
                                    "browsers": ["last 2 versions", "ie >= 8", "safari >= 7"]
                                },
                                debug: true
                            }]
                        ]
                    }
                }]
            },
            {
                test: /\.css/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                modules: true,
                                localIdentName: '[name]_[local]__[hash:base64:5]'
                            }
                        },
                        'postcss-loader'
                    ]
                })
            },
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                modules: false,
                                sourceMap: true,
                                importLoaders: 2,
                                localIdentName: '[name]_[local]__[hash:base64:5]'
                            }
                        },
                        'sass-loader'
                    ]
                })
            },
            {
                test: /\.(eot|woff|woff2|ttf|svg|png|jpe?g|gif)(\?\S*)?$/,
                use: [
                    {
                        loader:  'url-loader',
                        options: {
                            limit: 100000,
                            name: '[name].[ext]'
                        }
                    }
                ]
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.jsx'],
        modules: ['node_modules', 'src']
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development')
        }),
        new HtmlWebpackPlugin({
            template: path.join(Paths.src, 'index.html')
        }),
        new ExtractTextPlugin({filename: "[name].[contenthash].css", allChunks: true}),
        new CopyWebpackPlugin([
            {from: 'assets/images/**/*', to: ''},
            {from: 'assets/fonts/**/*', to: ''},
            {from: 'assets/lang/**/*', to: ''},
            {from: 'assets/js/**/*', to: ''},
            {from: 'src/static/**/*', to: ''}
            ]),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin()
    ],
    devServer: {
        port: 8081,
        host: '127.0.0.1',
        disableHostCheck: true, // so you can use the computers IP address not just 'localhost'/127.0.0.1
        contentBase: Paths.src,
        historyApiFallback: true,
        hot: true,
        headers: {
            "Access-Control-Allow-Origin": "http://localhost:8081",
            "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
            "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
        },
        inline: true
        }
    }
};