2015-06-14 121 views
17

到目前爲止,我一直在使用livereload,以便每當我更改JS或模板時,頁面刷新,並且當我更改CSS時,它將熱切換新CSS而不刷新。webpack熱模塊替換:css不刷新

我嘗試了webpack現在和幾乎得到相同的行爲,有一個例外:當CSS更改,刷新整個窗口。是否有可能讓它在沒有刷新的情況下熱切CSS?

配置至今:

var webpackConfig = { 
    entry: ["webpack/hot/dev-server", __dirname + '/app/scripts/app.js'], 
    debug: true, 
    output: { 
     path: __dirname + '/app', 
     filename: 'scripts/build.js' 
    }, 
    devtool: 'source-map', 
    plugins: [ 
     new webpack.HotModuleReplacementPlugin(), 
     new htmlWebpackPlugin({ 
      template: __dirname + '/app/index.html', 
      inject: 'body', 
      hash: true, 
      config: config 
     }), 
     new webpack.ProvidePlugin({ 
      'angular': 'angular' 
     }), 
     new ExtractTextPlugin("styles.css") 
    ], 
    module: { 
     loaders: [ 
      { 
       test: /\.scss$/, 
       loader: "style!css!sass?includePaths[]=" + __dirname + "/app/bower_components/compass-mixins/lib&includePaths[]=" + __dirname + '/instance/sth/styles&includePaths[]=' + __dirname + '/app/scripts' 
      } 
     ] 
    } 
}; 

回答

16

這是使用ExtractTextPluginthe project README指出的缺點之一。您可以通過拆分配置來解決問題。 IE瀏覽器。沒有它就有單獨的開發配置,有一個用於開發它。

+1

我已經創建了https://github.com/sheerun/extracted-loader來解決這個問題 – sheerun

4

現在可以使用angular2,帶有熱模塊替換的webpack,sass源代碼和外部加載的css。花了我幾天的時間玩它,但我得到它的工作!

的依賴關係是style-loadercss-loader,和sass-loader(如果使用SASS,若否,SASS裝載機可以被移除)

我使用ExtractTextPlugin生產模式來發射實際的CSS文件。

注意:爲了使它起作用,我不使用stylesUrl屬性,而是將.scss文件導入@Component裝飾器之外,以便樣式在全局上下文中加載,而不是由組件作用域。

該配置允許使用webpack開發服務器使用SCSS文件進行熱模塊替換,並將extracttextplugin用於生產模式以發佈實際的.css文件。

這是我的工作配置

{ 
     test: /\.(scss)$/, 
     use: 
      isDevServer ? [ 
       { 
       loader: 'style-loader', 
       },    
       { 
       loader: 'css-loader', 
       options: { sourceMap: true } 
       }, 
       { 
       loader: 'postcss-loader', 
       options: { postcss: [AutoPrefixer(autoPrefixerOptions)], sourceMap: true } 
       }, 
       { 
       loader: 'sass-loader', 
       options: { sourceMap: true } 
       }, 
       { 
       loader: 'sass-resources-loader', 
       options: { 
        resources: [ 
        './src/assets/styles/variables.scss', 
        './src/assets/styles/mixins.scss'] 
       } 
       }, 
       /** 
       * The sass-vars-loader will convert the 'vars' property or any module.exports of 
       * a .JS or .JSON file into valid SASS and append to the beginning of each 
       * .scss file loaded. 
       * 
       * See: https://github.com/epegzz/sass-vars-loader 
       */ 
       { 
       loader: '@epegzz/sass-vars-loader?', 
       options: querystring.stringify({ 
        vars: JSON.stringify({ 
        susyIsDevServer: susyIsDevServer 
        }) 
       }) 
       }] : // dev mode 
      ExtractTextPlugin.extract({ 
      fallback: "css-loader", 
      use: [ 
       { 
       loader: 'css-loader', 
       options: { sourceMap: true } 
       }, 
       { 
       loader: 'postcss-loader', 
       options: { postcss: [AutoPrefixer(autoPrefixerOptions)], sourceMap: true } 
       }, 
       { 
       loader: 'sass-loader', 
       options: { sourceMap: true } 
       }, 
       { 
       loader: 'sass-resources-loader', 
       options: { 
        resources: [ 
        './src/assets/styles/variables.scss', 
        './src/assets/styles/mixins.scss'] 
       } 
       }, { 
       loader: '@epegzz/sass-vars-loader?', 
       options: querystring.stringify({ 
        vars: JSON.stringify({ 
        susyIsDevServer: susyIsDevServer 
        }) 
        // // Or use 'files" object to specify vars in an external .js or .json file 
        // files: [ 
        // path.resolve(helpers.paths.appRoot + '/assets/styles/sass-js-variables.js') 
        // ], 
       }) 
       }], 
      publicPath: '/' // 'string' override the publicPath setting for this loader 
      }) 
     }, 

然後,在你的組件,例如,app.component.ts,你會需要你的app.style.scss文件OUTSIDE的@Component裝飾的。

這就是訣竅。如果您使用stylesUrl加載樣式「角度方式」,這將不起作用。這樣做會允許您爲延遲加載的組件延遲加載.css樣式表,使初始加載時間更快。

app.component.css

/* 
* THIS IS WHERE WE REQUIRE CSS/SCSS FILES THAT THIS COMPONENT NEEDS 
* 
* Function: To enable so-called "Lazy Loading" CSS/SCSS files "on demand" as the app views need them. 
* Do NOT add styles the "Angular2 Way" in the @Component decorator ("styles" and "styleUrls" properties) 
*/ 
    import './app.style.scss' 

/** 
* AppComponent Component 
* Top Level Component 
*/ 
@Component({ 
    selector: 'body', 
    encapsulation: ViewEncapsulation.None, 
    host: { '[class.authenticated]': 'appState.state.isAuthenticated' }, 
    templateUrl: './app.template.html' 
}) 

我已經運行此安裝沒有問題。幹得好!

sass_sourcemaps _hmr _wds

更新08/2017:改進的配置爲的WebPack 3+架構要求,並與角4 AOT編譯工作。

+0

謝謝你的廣泛答案。我還需要嘗試一下,這可能需要一段時間,因爲我們將webpack項目停放了一段時間,但您的答案看起來很有希望! –

1

儘管ExtractTextPlugin在其README section,中聲明「無熱模塊更換」,但我通過BrowserSync API手動更新CSS文件來解決此問題。

我使用gaze來偵聽我的CSS文件中的任何更改,然後使用BrowserSync更新它們。

npm install gaze 

你也可以很容易地通過下面的一些編輯構建腳本,這樣做的:

const { Gaze } = require('gaze'); 

    // Your own BrowserSync init 
    browserSync.init({ 
    ... 
    }, resolve); 

    // Create a watcher: 
    // You can watch/reload specific files according to your build/project structure 
    const gaze = new Gaze('**/*.css'); 
    gaze.on('all',() => bs.reload('*.css')); 

希望有所幫助。

2

實際上有一個簡單的方法來做到這一點。我使用sass-loader和提取文本插件來生成css文件。

你需要做的是添加ID到你的CSS包括

<link id="js-style" type="text/css" rel="stylesheet" href="/static/main.css"> 

現在,你需要確保當HMR發生了,你與當前版本/時間戳更新URL。你可以這樣做:

import '../style/main.scss' 
if (module.hot) { 
    module.hot.accept('../style/main.scss',() => { 
    const baseStyle = window.document.getElementById('js-style') 
    baseStyle.setAttribute('href', '/static/main.css?v=' + new Date().valueOf) 
    }) 
} 

所以,每當css發生變化,我們將修復css include的url來重新加載它。

相關問題