Как мне использовать изображения отпечатков пальцев и другие статические ресурсы в Ionic для очистки кеша?

Я расширил конфигурацию веб-пакета по умолчанию в Ionic v3 для принудительной очистки кеша.

Я могу снимать отпечатки сгенерированных артефактов JavaScript, но я не могу снимать отпечатки пальцев с изображений и файлов JSON в папке с ресурсами. Взял Help от 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
}

Вы запускали сборку в режиме prod?

emix 27.12.2018 10:44

@emix да, я сделал AFAIK Angular предоставляет нам output-hashing, но ionic нет, поэтому я перешел в конфигурацию webpack для хеширования

Vikas 27.12.2018 10:46

как насчет этого [hash] -> loader: 'url-loader? limit = 1024 & name = images / [name] [hash]. [ext] ‌'

Vadim Hulevich 30.12.2018 10:02

Вы видели этот другой ТАК вопрос? stackoverflow.com/questions/43064019/…

Derek Nguyen 02.01.2019 05:40

@DerekNguyen да, но без помощи

Vikas 02.01.2019 06:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
19
5
5 307
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Используя webpack-assets-manifest, вы можете сгенерировать карту имен активов с отпечатанными именами следующим образом:

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

Используя этот манифест, вы затем можете переименовать активы в целевой папке и использовать в своем проекте «правильный», содержащий хэш-код src или href.

Исправление не зависит от платформы.

Дай мне попробовать

Vikas 10.01.2019 04:50

Это не решает мой проблемный путь в шаблоне HTML, и CSS не обновляются. Я должен использовать для него специальный сценарий, которого я не хочу, я хочу, чтобы веб-пакет для отпечатков пальцев и обновлял пути в соответствующих файлах соответственно, спасибо за ваш помогите, но то же самое можно сделать и с помощью хеширования :)

Vikas 11.01.2019 06:15

Вы должны использовать загрузчики (Survivaljs.com/webpack/loading/images), чтобы использовать хеширование веб-пакетов, или вам нужно использовать внешнее хеширование. Использование манифеста и обновление ссылок до связывание - лучший вариант. Если вы не используете загрузчики для некоторых ресурсов, вы не сможете использовать хеширование веб-пакетов для этих ресурсов! Если вы не хотите брать манифест и программно обновлять хэши активов перед объединением, заплатите фрилансеру.

Oleg 16.01.2019 23:06

Не могли бы вы подробнее рассказать о Using this manifest you can then rename the assets in destination folder, and use the "correct", hash-inclusive src or href in your project.

Pants 06.01.2020 16:56

При использовании Webpack 4 вам не понадобятся дополнительные плагины или загрузчики.

Это даст вам вариант именования [contenthash].

Кроме того, похоже, что у вас есть этот блок, вложенный в блок test: .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, сделайте это, но в противном случае для получения дополнительной информации см. Эта проблема для объяснения.

Для получения дополнительной помощи прочтите руководство по долгосрочному кешированию от Google и последнюю документацию по кешированию от Webpack.

Если я выберу webpack 4, мне придется переделать весь проект, что невозможно на данном этапе. Мне нужно найти обходной путь, расширив конфигурацию ionic webpack. 1 paulsouche / angular6-ionic4-webpack4-стартер Это репо имеет ту же конфигурацию, о которой вы упомянули. с минимальными изменениями К сожалению, я не могу использовать это решение Большое спасибо :)

Vikas 12.01.2019 07:35

Как я могу сделать то же самое, но с файлами JSON? Я хотел бы получить строку имени файла JSON с хешем, когда я использую import json from './file.json', вместо объекта JS. Является ли это возможным?

tonix 01.10.2019 21:53

Как правило, вы хотите «очистить кеш», изменив фактическое имя файла при изменении содержимого под ним ... вы можете выполнить хеширование файлов самостоятельно и добавить «хеш» к имени.

adamrights 25.10.2019 03:36

файлы, скопированные через 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',
      },
    ]),
  ],
};
Ответ принят как подходящий

В конце концов, я использовал gulp для снятия отпечатков пальцев со статических активов.

  1. Отбросьте хеширование вывода Angular и создайте приложение.
  2. после сборки выполнить сценарий gulp, который отпечатает все активы и обновит ссылки.
npm i gulp gulp-rev gulp-rev-delete-original gulp-rev-collector

gulpfile.js

const gulp = require('gulp');
const rev = require('gulp-rev');
const revdel = require('gulp-rev-delete-original');
const collect = require('gulp-rev-collector');

// finger priniting static assets
gulp.task('revision:fingerprint', () => {
  return gulp
    .src([
      'dist/welcome/**/*.css',
      'dist/welcome/**/*.js',
      'dist/welcome/**/*.{jpg,png,jpeg,gif,svg,json,xml,ico,eot,ttf,woff,woff2}'
    ])
    .pipe(rev())
    .pipe(revdel())
    .pipe(gulp.dest('dist/welcome'))
    .pipe(rev.manifest({ path: 'manifest-hash.json' }))
    .pipe(gulp.dest('dist'));
});

gulp.task('revision:update-fingerprinted-references', () => {
  return gulp
    .src(['dist/manifest-hash.json', 'dist/**/*.{html,json,css,js}'])
    .pipe(collect())
    .pipe(gulp.dest('dist'));
});
gulp.task(
  'revision',
  gulp.series(
    'revision:fingerprint',
    'revision:update-fingerprinted-references'));

Добавьте новый скрипт в package.json

ng build --prod --aot --output-hashing none

Выполните "gulp-revision": "gulp revision" Post-build.

npm run gulp-revision

Другие вопросы по теме