전단-프로젝트 패키지 시 js, css 등 파일
전단-공정 패키지 시 js, css 등 파일의 파일 이름을hash처리하여 클라이언트 브라우저가 오래된 코드를 캐시하는 경우 새 버전의 코드가 있을 때 클라이언트가 이러한 불확실성을 가질 수 있습니다
angular의 프로젝트에 대해 이렇게 포장할 수 있습니다:ngbuild -prod --output-hashing=all
But those hashed bundles are great, because it solves a common issue with browser and proxy servers caching old versions of your scripts. Don't underestimate this as it can generate all kinds of strange behavior for users.
That means we need a solution which works with dynamically changing file names, just having URLs in the template wouldn't do it!
http://michaco.net/blog/Angular4GettingHashedWebpackBundlesWorkingInASPNETCoreMVC
// Adding Hashes to Filenames
https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/
Unicon - Wrangle SVGs from your favorite design tool - Interview with Travis Arnold
Even though the generated build works the file names it uses is problematic. It doesn't allow to leverage client level cache efficiently as there's no way tell whether or not a file has changed. Cache invalidation can be achieved by including a hash to the filenames.
Placeholders
Webpack provides placeholders for this purpose. These strings are used to attach specific information to webpack output. The most valuable ones are:
[id]
- Returns the chunk id. [path]
- Returns the file path. [name]
- Returns the file name. [ext]
- Returns the extension. [ext]
works for most available fields. MiniCssExtractPlugin
is a notable exception to this rule. [hash]
- Returns the build hash. If any portion of the build changes, this changes as well. [chunkhash]
- Returns an entry chunk-specific hash. Each entry
defined in the configuration receives a hash of its own. If any portion of the entry changes, the hash will change as well. [chunkhash]
is more granular than [hash]
by definition. [contenthash]
- Returns a hash generated based on content. It's preferable to use particularly
hash
and chunkhash
only for production purposes as hashing doesn't do much good during development. It's possible to slice
hash
and chunkhash
using specific syntax: [chunkhash:4]
. Instead of a hash like 8c4cbfdb91ff93f3f3c5
this would yield 8c4c
. There are more options available, and you can even modify the hashing and digest type as discussed at loader-utils documentation.
Example Placeholders
Assume you have the following configuration:
{
output: {
path: PATHS.build,
filename: "[name].[chunkhash].js",
},
},
Webpack would generate filenames like these based on it:
main.d587bbd6e38337f5accd.js
vendor.dc746a5db4ed650296e1.js
If the file contents related to a chunk are different, the hash changes as well, thus the cache gets invalidated. More accurately, the browser sends a new request for the new file. If only
main
bundle gets updated, only that file needs to be requested again. The same result can be achieved by generating static filenames and invalidating the cache through a querystring (i.e.,
main.js?d587bbd6e38337f5accd
). The part behind the question mark invalidates the cache. According to Steve Souders, attaching the hash to the filename is the most performant option. Setting Up Hashing
The build needs tweaking to generate proper hashes. Images and fonts should receive
hash
while chunks should use chunkhash
in their names to invalidate them correctly: webpack.config.js
const productionConfig = merge([
{ output: { chunkFilename: "[name].[chunkhash:4].js", filename: "[name].[chunkhash:4].js", }, },
... parts.loadImages({ options: { limit: 15000,
name: "[name].[ext]",
name: "[name].[hash:4].[ext]",
}, }), ... ]);
[hash]
is defined differently for file-loader than for the rest of webpack. It's calculated based on file
content. See file-loader documentation for further information.
If you used
chunkhash
for the extracted CSS as well, this would lead to problems as the code points to the CSS through JavaScript bringing it to the same entry. That means if the application code or CSS changed, it would invalidate both. Therefore, instead of
chunkhash
, you can use contenthash
that is generated based on the extracted content: webpack.parts.js
exports.extractCSS = ({ include, exclude, use }) => {
// Output extracted CSS to a file
const plugin = new MiniCssExtractPlugin({
filename: "[name].css",
filename: "[name].[contenthash:4].css",
}); ... };
The hashes have been sliced to make the output fit better in the book. In practice, you can skip slicing them.
If you generate a build now (
npm run build
), you should see something: Hash: fb67c5fd35454da1d6ff
Version: webpack 4.1.1
Time: 3034ms
Built at: 3/16/2018 6:18:07 PM
Asset Size Chunks Chunk Names
0.0847.js 161 bytes 0 [emitted]
vendors~main.d2f1.js 96.8 KiB 1 [emitted] vendors~main
main.745c.js 2.25 KiB 2 [emitted] main
main.5524.css 1.2 KiB 2 [emitted] main
vendors~main.3dd5.css 1.32 KiB 1 [emitted] vendors~main
0.0847.js.map 203 bytes 0 [emitted]
vendors~main.d2f1.js.map 235 KiB 1 [emitted] vendors~main
main.745c.js.map 11.4 KiB 2 [emitted] main
index.html 349 bytes [emitted]
Entrypoint main = vendors~main.d2f1.js ...
...
The files have neat hashes now. To prove that it works for styling, you could try altering src/main.css and see what happens to the hashes when you rebuild.
There's one problem, though. If you change the application code, it invalidates the vendor file as well! Solving this requires extracting a manifest, but before that, you can improve the way the production build handles module IDs.
Conclusion
Including hashes related to the file contents to their names allows to invalidate them on the client side. If a hash has changed, the client is forced to download the asset again.
To recap:
[name]
, [chunkhash]
, and [ext]
. A chunk hash is derived based on the entry in which the asset belongs. MiniCssExtractPlugin
, you should use [contenthash]
. This way the generated assets get invalidated only if their content changes. Even though the project generates hashes now, the output isn't flawless. The problem is that if the application changes, it invalidates the vendor bundle as well. The next chapter digs deeper into the topic and shows you how to extract a manifest to resolve the issue.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Qiita API v2를 Ajax에서 사용하기위한 webpack 설정 (로컬 개발 환경 전용)에서는 Qiita의 기사 목록, 사용자 세부 정보, 기사를 '좋아요'한 사람 목록 및 재고가 있는 사람 목록을 검색할 수 있습니다. Qiita 화면에서 기사를 재고한 사람을 볼 수 없기 때문에 API를 통해 기사를 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.