web-dev-qa-db-ja.com

webpackホットモジュールの交換:更新なしのcss

これまで私はlivereloadを使用していたため、JSまたはテンプレートを変更するたびにページが更新され、CSSを変更すると、更新せずに新しいCSSがホットスワップされます。

私は今Webpackを試しているところ、CSSが変更されるとウィンドウ全体が更新されるという1つの例外を除いて、ほぼ同じ動作になりました。更新せずに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'
            }
        ]
    }
};
19

プロジェクトのREADME で述べられているように、これはExtractTextPluginを使用することの欠点の1つです。設定を分割することで問題を解決できます。つまり。それを使用しない開発用の構成と、それを使用する本番用の構成があります。

17

Angular2、ホットモジュール置換のwebpack、sassソースマップ、および外部からロードされたcssを使用できるようになりました。私はそれで遊んで数日かかりましたが、私はそれを働かせました!

依存関係はstyle-loadercss-loadersass-loader(sassを使用している場合、使用していない場合は、sassローダーを削除できます)

本番モードでExtractTextPluginを使用して、実際の.cssファイルを出力します。

注:これを機能させるために、私はstylesUrlプロパティを使用せず、@ Componentデコレーターの外部に.scssファイルをインポートして、スタイルがコンポーネントによってスコープされるのではなく、グローバルコンテキストでロードされるようにします。

この構成では、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ファイル@ 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

2017年8月更新:webpack 3+スキーマ要件の構成を改善し、Angular 4 AOTコンパイルで動作するようにしました。

4
TetraDev

これを行う簡単な方法があります。私は、CSSファイルを生成する抽出テキストプラグインでsassローダーを使用しています。

あなたがする必要があるのはCSSインクルードにIDを追加することです

  <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インクルードのURLを修正して再読み込みします。

3
Hatch

ExtractTextPluginは READMEセクション に「ホットモジュールの置き換えなし」と記載していますが、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'));

お役に立てば幸いです。

1
urip

'css-hot-loader'を使用して、抽出したCSSのHMRを有効にすることができます。それは完全に私のために働きます。

0
ddemakov