sass 的 webpack 实时热重载

webpack live hot reload for sass

我正在为 React Starter 构建一个工作流,并且希望在我更改我的 scss 文件时让我的浏览器自动重新加载。

目前,当我在我的 index.js 文件(设置为我的入口点)中进行更改时,webpack 将热重新加载。但是,当我在 scss 文件中 change/add scss 代码时,它会被编译,但 css 不会在任何地方输出,也不会触发浏览器重新加载。

我是 webpack 的新手,非常感谢这里的一些见解。

这是我的 webpack.config.js

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

module.exports = {
    entry: ['./src/js/index.js', './src/scss/style.scss'],
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'js/index_bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.scss$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].css',
                            outputPath: 'css/'
                        }
                    },
                    {
                        loader: 'extract-loader'
                    },
                    {
                        loader: 'css-loader'
                    },
                    {
                        loader: 'postcss-loader'
                    },
                    {
                        loader: 'sass-loader'
                    }
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'    
        })
    ]
}

我的 index.js 入口点文件

import React from 'react';
import ReactDOM from 'react-dom';
import App from '../components/App';


ReactDOM.render(
    <App/>,
    document.getElementById('App')
);

还有我的 App 组件

import React, {Component} from 'react';
import '../../dist/css/style.css';



class App extends Component {
    render() {
        return (
            <div>
                <p>Test</p>         
            </div>
        )
    }
}

export default App;

实际上,style-loader 是 CSS HMR 的 responsible

您应该将其添加到样式管道的末尾,仅适用于开发人员。 对于生产,您可以保留您的配置。

它应该看起来像这样:

const devMode = process.env.NODE_ENV !== 'production'

{
  test: /\.scss$/,
  use: [
    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
    {
      loader: 'css-loader'
    },
    {
      loader: 'postcss-loader'
    },
    {
      loader: 'sass-loader'
    }
  ]
}

注意,如果你使用的 webpack < 4.

尝试使用 Parcel 而不是 Webpack。我过去常常花几个小时配置 Webpack 来使热重载等功能正常工作。使用 Parcel,大多数事情只是 "work" 而没有配置文件。例如,我想开始使用 Pug 模板。 Parcel 识别了 .pug 扩展并自动下载了所需的 NPM 依赖项!

在您的情况下,只需将 SCSS 文件包含在您的应用程序中,如下所示:import '../scss/style.scss'(注意路径是相对于 index.js 的 .scss 源文件)。 Parcel 将自动执行 "sensible" 操作。

这里有一些开始使用 Parcel + React + 的参考资料 SASS:


Parcel 与 WebPack 的显着优缺点:

  • Parcel 需要最少的配置;经常没有配置。
  • Parcel 的构建速度通常比 WebPack 快得多。
  • WebPack 开发服务器似乎更稳定。 (Parcel 开发服务器需要偶尔重新启动一次并且不能很好地与 Dropbox 配合使用。显然这应该在 2.0 版中修复。)
  • 当需要(不常见的)配置时,在 Parcel 中如何进行配置可能并不明显;至少在 WebPack 中,所有配置都集中在一个地方。
  • 有时 Parcel 的自动配置会做一些人们意想不到的事情,让他们感到困惑。
npm install --save-dev style-loader CSS-loader
npm install --save-dev html-webpack-plugin

在 package.json 添加一个 npm 脚本到 运行 webpack-dev-server:

"scripts": { 
  "start": "webpack-dev-server" 
}, 

Webpack 需要一个配置文件来了解如何处理您在我们的应用程序中使用的不同类型的依赖项,为此创建一个名为 webpack.config.js 的文件, 在 webpack.config.js 中添加三个属性: 第一个是入口,它告诉 Webpack 我们应用程序的主文件在哪里:

entry: './index.js'

第二个是模块,就是我们告诉Webpack如何加载外部依赖的地方。它有一个名为加载器的属性,我们为每种文件类型设置一个特定的加载器:

module: { 
 loaders: [ 
{ 
  test: /\.js$/, 
  exclude: /(node_modules|bower_components)/, 
  loader: 'babel', 
  query: { 
    presets: ['es2015', 'react'], 
  } 
}, 
{ 
  test: /\.css$/, 
  loader: 'style!css?}]}

我们说的是匹配 .js 正则表达式的文件是使用 babel-loader 加载的,以便它们被转译并加载到包中。 loaders 数组中的第二个条目告诉 Webpack 在导入 CSS 文件时要做什么,它使用启用了模块标志的 css-loader 来激活 CSS 模块。然后将转换的结果传递给样式加载器,样式加载器将样式注入页面的头部。

最后,我们启用 HTML 插件来为我们生成页面。

const HtmlWebpackPlugin = require('html-webpack-plugin') 

plugins: [new HtmlWebpackPlugin()]