sass 的 webpack 实时热重载

Posted

技术标签:

【中文标题】sass 的 webpack 实时热重载【英文标题】:webpack live hot reload for sass 【发布时间】:2019-02-02 06:03:36 【问题描述】:

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

目前,当我对 index.js 文件(设置为我的入口点)进行更改时,webpack 将热重新加载。但是,当我在我的 scss 文件中更改/添加 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;

【问题讨论】:

两天前我提出了一个关于 MiniCSS 的更具体的问题。此赏金也适用于:***.com/questions/56318991/… 【参考方案1】:

实际上,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,最好将 css 提取到一个单独的文件中,使用MiniCssExtractPlugin,如果你使用 webpack ExtractTextWebpackPlugin

【讨论】:

我添加了这个但是现在当使用我的构建命令时我没有在我的 dist 目录中得到一个已编译的.生成的 css 文件 在开发模式下,您将使用样式加载器,这意味着您的 css 将在文件中。只有在生产模式下,您才会获得一个外部 css 文件 这正是我所缺少的。由于某种原因,webpack-dev-server 在不使用 css 模块的情况下导入时不应用样式表(import 'styles.css')...【参考方案2】:

尝试使用 Parcel 代替 Webpack。我曾经花费数小时配置 Webpack 以使诸如热重载之类的工作正常工作。使用 Parcel,大多数事情都可以在没有配置文件的情况下“工作”。例如,我想开始使用 Pug 模板。 Parcel 识别出.pug 扩展并自动下载所需的 NPM 依赖项!

在您的情况下,只需将 SCSS 文件包含在您的应用中,如下所示:import '../scss/style.scss'(注意路径是相对于 index.js 的 .scss 源文件)。 Parcel 会自动做“明智”的事情。

以下是 Parcel + React + SASS 入门的一些参考资料:

Build a React web app with Parcel.js lightning fast Parcel SCSS documentation

Parcel 与 WebPack 的显着优缺点:

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

【讨论】:

我同意 Parcel 的一切。不幸的是,我正在进行的项目是使用 WebPack 构建的,并且保留它是绝对必要的。所以我需要通过 MiniCSS,正如我自己的问题中所解释的那样:***.com/questions/56318991/…【参考方案3】:
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 中添加三个属性: 第一个是entry,它告诉Webpack我们应用的主文件在哪里:

entry: './index.js'

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

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 文件时要做什么,它使用启用 modules 标志的 css-loader 来激活 CSS 模块。然后将转换的结果传递给样式加载器,后者将样式注入页面头部。

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

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

plugins: [new HtmlWebpackPlugin()] 

【讨论】:

以上是关于sass 的 webpack 实时热重载的主要内容,如果未能解决你的问题,请参考以下文章

webpack 热重载的3种方式

第562期用 webpack 构建 node 后端代码,使其支持 js 新特性并实现热重载

vue-cli结构分析

Webpack2 不理解我的 SASS 文件中的 @import 语句(如何使用 webpack2 编译 SASS?)

Webpack:热重载不起作用,但更改编译

启用单页应用响应热重载 webpack