web-dev-qa-db-ja.com

Ionicキャッシュ無効化の画像やその他の静的アセットにハッシュを追加するにはどうすればよいですか?

キャッシュバスターを強制するためにIonic v3でデフォルトのWebパック設定を拡張しました。

生成されたJavaScriptアーティファクトをフィンガープリントできますが、アセットフォルダーの下の画像とJSONファイルをフィンガープリントできません。 Bundled files and cache busting からヘルプを取得しました。

webpack config.jsの抜粋

module.exports = {
  // ...
  output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].js',
  },
  plugins: [
    new WebpackChunkHash({algorithm: 'md5'}) // 'md5' is default value
  ]
}

上記はJavaScriptバンドルをフィンガープリントするためのアプローチであり、正常に機能しています。アセットフォルダー内にハッシュ/指紋画像とJSONファイルを追加したい。画像にも同じアプローチを使用しましたが、うまくいきませんでした。

Webpack config.jsを拡張し、画像の新しいルールを追加しました。デフォルトでは、webpackは画像とアセットを出力フォルダーに直接コピーします。

Config.jsをコピー

module.exports = {
  copyAssets: {
    src: ['{{SRC}}/assets/**/*'],
    dest: '{{WWW}}/assets'
  },
  copyIndexContent: {
    src: ['{{SRC}}/index.html', '{{SRC}}/manifest.json', '{{SRC}}/service-worker.js'],
    dest: '{{WWW}}'
  },
  copyFonts: {
    src: ['{{ROOT}}/node_modules/ionicons/dist/fonts/**/*', '{{ROOT}}/node_modules/ionic-angular/fonts/**/*'],
    dest: '{{WWW}}/assets/fonts'
  },

ここでは、画像やその他のアセットが直接コピーされます。拡張webpack.config.jsに新しいルールを追加しましたが、ビルドプロセスはそれを無視しています。この問題を修正するにはどうすればよいですか?

webpack config.jsの抜粋

 {
        test: /\.(png|jpg|gif)$/,
        loader: 'file-loader',
        options: {

            name:'[name].[hash].[ext]',//adding hash for cache busting
            outputPath:'assets/imgs',
            publicPath:'assets/imgs'


        },

webpack.config.js全体

/*
 * The webpack config exports an object that has a valid webpack configuration
 * For each environment name. By default, there are two Ionic environments:
 * "dev" and "prod". As such, the webpack.config.js exports a dictionary object
 * with "keys" for "dev" and "prod", where the value is a valid webpack configuration
 * For details on configuring webpack, see their documentation here
 * https://webpack.js.org/configuration/
 */

var path = require('path');
var webpack = require('webpack');
var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY);

var ModuleConcatPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
var PurifyPlugin = require('@angular-devkit/build-optimizer').PurifyPlugin;

var optimizedProdLoaders = [
  {
    test: /\.json$/,
    loader: 'json-loader'
  },
  {
    test: /\.js$/,
    loader: [
      {
        loader: process.env.IONIC_CACHE_LOADER
      },

      {
        loader: '@angular-devkit/build-optimizer/webpack-loader',
        options: {
          sourceMap: true
        }
      },
    ]
  },
  {
    test: /\.ts$/,
    loader: [
      {
        loader: process.env.IONIC_CACHE_LOADER
      },

      {
        loader: '@angular-devkit/build-optimizer/webpack-loader',
        options: {
          sourceMap: true
        }
      },
      {
        test: /\.(png|jpg|gif)$/,
        loader: 'file-loader',
        options: {

            name:'[name].[hash].[ext]',
            outputPath:'assets/imgs',
            publicPath:'assets/imgs'
        },
      },


      {
        loader: process.env.IONIC_WEBPACK_LOADER
      }
    ]
  }
];

function getProdLoaders() {
  if (process.env.IONIC_OPTIMIZE_JS === 'true') {
    return optimizedProdLoaders;
  }
  return devConfig.module.loaders;
}

var devConfig = {
  entry: process.env.IONIC_APP_ENTRY_POINT,
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
  },
  devtool: process.env.IONIC_SOURCE_MAP_TYPE,

  resolve: {
    extensions: ['.ts', '.js', '.json'],
    modules: [path.resolve('node_modules')]
  },

  module: {
    loaders: [
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.ts$/,
        loader: process.env.IONIC_WEBPACK_LOADER
      },
      {
      test: /\.(jpg|png)$/,
         use: {
         loader: "file-loader",
         options: {
         name: "[name].[hash].[ext]",
         outputPath:'assets/imgs',
         publicPath:'assets/imgs'

    },
  }},
    ]
  },

  plugins: [
    ionicWebpackFactory.getIonicEnvironmentPlugin(),
    ionicWebpackFactory.getCommonChunksPlugin()
  ],

  // Some libraries import Node.js modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
};

var prodConfig = {
  entry: process.env.IONIC_APP_ENTRY_POINT,
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
  },
  devtool: process.env.IONIC_SOURCE_MAP_TYPE,

  resolve: {
    extensions: ['.ts', '.js', '.json'],
    modules: [path.resolve('node_modules')]
  },

  module: {
    loaders: getProdLoaders()
  },

  plugins: [
    ionicWebpackFactory.getIonicEnvironmentPlugin(),
    ionicWebpackFactory.getCommonChunksPlugin(),
    new ModuleConcatPlugin(),
    new PurifyPlugin()
  ],

  // Some libraries import Node.js modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
};


module.exports = {
  dev: devConfig,
  prod: prodConfig
}
16
Vikas

Webpack 4を使用すると、追加のプラグインやローダーは必要ありません。

命名オプション[contenthash]が提供されます。

また、このブロックはテストの下にネストされているように見えます:.tsブロック。

{
    test: /\.(png|jpg|gif)$/,
    loader: 'file-loader',
    options: {

        name:'[name].[hash].[ext]', // Adding hash for cache busting
        outputPath:'assets/imgs',
        publicPath:'assets/imgs'
    },

最終的に、次のようなことができます。

    // Copy static assets over with file-loader
    {
        test: /\.(ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'file-loader', options: {name: '[name].[contenthash].[ext]'},
    },
    {
        test: /\.(woff|woff2|eot|ttf|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'file-loader', options: {name: 'fonts/[name].[contenthash].[ext]'},
    },
    {
        test: /\.(jpg|gif|png|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'file-loader', options: {name: 'images/[name].[contenthash].[ext]'},
    }
]

コンテンツの代わりに[chunkhash]を使用しても動作するはずです。webpack4を使用していない場合はそれを実行しますが、詳細については this issue を参照してください。

詳細については、 Googleの長期キャッシュパフォーマンスガイド および最新のキャッシュドキュメントを Webpack からお読みください。

1
adamrights

webpack-assets-manifest 次のように、アセット名とフィンガープリントされた名前のマップを生成できます。

{
  "images/logo.svg": "images/logo-b111da4f34cefce092b965ebc1078ee3.svg"
}

このマニフェストを使用して、宛先フォルダーのアセットの名前を変更し、プロジェクトで「正しい」ハッシュを含むsrcまたはhrefを使用できます。

修正はフレームワーク固有ではありません。

0
o.v.

copyPluginを介してコピーされたファイルはローダーに渡されません。したがって、画像のハッシュ名を使用して正しいローダー設定を行っても、機能しません。

しかし、あなたは見ることができます https://github.com/webpack-contrib/copy-webpack-plugin#template

copyPluginは、ハッシュで設定できる出力名を指定する方法を提供します。

module.exports = {
  plugins: [
    new CopyPlugin([
      {
        from: 'src/',
        to: 'dest/[name].[hash].[ext]',
        toType: 'template',
      },
    ]),
  ],
};
0
Yi Feng Xie