摘要:在的配置項中,可能會見到這樣的字符。的情況的可以指定。值是特定于整個構建過程的。。因此,以上兩個值中更推薦的是。中的則和前面的一樣,指定了結果的截取長度。的情況被引用的通過來得到帶的文件。所以,這可能并不是我們想要的。
在webpack的配置項中,可能會見到hash這樣的字符。
當存在hash配置的時候,webpack的輸出將可以得到形如這樣的文件:
page1_bundle_54e8c56e.js
這種帶哈希值的文件名,可以幫助實現靜態資源的長期緩存,在生產環境中非常有用。關于這一點的詳細內容,可以參考這篇久遠的大公司里怎樣開發和部署前端代碼。
在webpack中配置hash下面是一個帶hash輸出的webpack配置的例子(webpack v3.0.0):
var env = { src: path.resolve(__dirname, "./src"), output: path.resolve(__dirname, "./dist"), publicPath: "/" }; module.exports = { entry: { "page1": "./page1", "page2": "./page2" }, context: env.src, output: { path: env.output, filename: "./[name]/bundle_[chunkhash:8].js", publicPath: env.publicPath }, devtool: false, module: { rules: [{ test: /.(png|jpg)$/, use: "url-loader?limit=8192&name=[path][name]_[hash:8].[ext]" }, { test: /.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) }] }, plugins: [ new ExtractTextPlugin({ filename: "./[name]/style_[contenthash:8].css" }) ] };
可以看到,有多個地方都出現了hash這個詞,但形式不太一樣。
output的情況output的filename可以指定hash。有兩個值可以選擇:
[hash]。hash值是特定于整個構建過程的。
[chunkhash]。hash值是特定于每一個文件的內容的。
我們理想的緩存設計是,在一次版本更新(重新構建)后,只有當一個文件的內容確實發生了變化,它才需要被重新下載,否則應使用緩存。
因此,以上兩個值中更推薦的是[chunkhash]。你也可以閱讀這篇官方的緩存指南了解更多細節。
file-loader的情況url-loader和file-loader是同一家,參照file-loader文檔可知,文件名name可以使用標識符[hash]來啟用hash。此外,你還可以按照[
[hash:8]中的:8則和前面output的一樣,指定了hash結果的截取長度。
extract-text-webpack-plugin的情況被引用的css通過extract-text-webpack-plugin來得到帶hash的文件。參照extract-text-webpack-plugin文檔,在指定生成文件的文件名filename時可以使用標識符[contenthash](可以看到,和之前的并不相同)。
引用帶hash的文件當靜態資源的文件名變成這樣的帶哈希值的版本后,引用這些靜態資源就需要稍多花一點工夫。
純前端的情況如果沒有任何服務端,只是純html、css、js的前端應用的話,一般使用html-webpack-plugin。
例如,新建一個index.ejs模板文件如下:
App Example
然后增加html-webpack-plugin到webpack:
{ plugins: [ new HtmlWebpackPlugin({ template: "index.ejs" }) ] }
執行一次webpack構建,得到生成的index.html:
App Example
可以看到,html-webpack-plugin在模板文件內容的基礎上,就添加好了需要引用的bundle js。如果還有生成的css文件(通過extract-text-webpack-plugin),也會被添加到適當的位置。
純前端、多頁的情況如果webpack有多個entry文件,例如本文最前面給出的例子:
{ entry: { "page1": "./page1", "page2": "./page2" } }
在這種情況下,html-webpack-plugin會把全部entry的輸出都集中到一個.html里。所以,這可能并不是我們想要的。
我們更希望的是為每一個entry生成一個.html。這時候,可以使用的是multipage-webpack-plugin。這個插件實際也依賴了html-webpack-plugin。
例如,有這樣的目錄結構:
. ├─ package.json ├─ src │ ├─ page1 │ │ ├─ index.css │ │ ├─ index.ejs │ │ ├─ index.js │ │ └─ potofu.jpg │ └─ page2 │ ├─ index.css │ ├─ index.ejs │ └─ index.js └─ webpack.config.js
然后在webpack配置文件中加入multipage-webpack-plugin:
{ plugins: [ new MultipageWebpackPlugin({ htmlTemplatePath: "[name]/index.ejs", // 源模板文件的位置 bootstrapFilename: "manifest.js", templatePath: "[name]" // 輸出html文件的路徑 }), ] }
[name]標識符對應的是每一個entry的名稱(注意,在本文的時間點,需要使用multipage-webpack-plugin的master分支,也就是最新版,才支持此標識符)。在這個例子中,只有兩個取值:page1,page2。
bootstrapFilename如字面意義,是指保存webpack的bootstrap代碼的文件命名。而webpack的bootstrap代碼被這樣多帶帶放到一個文件里,是因為multipage-webpack-plugin在內部(強行)為你啟用了CommonsChunkPlugin。
執行一次webpack構建,得到的輸出結果:
dist ├─ manifest.js ├─ page1 │ ├─ bundle_29862ad6.js │ ├─ index.html │ ├─ potofu_26766d43.jpg │ └─ style_0b5ab6ef.css ├─ page2 │ ├─ bundle_6a9c6f12.js │ ├─ index.html │ └─ style_914dffd0.css └─ shared └─ bundle_9fa1a762.js
取其中一個page1/index.html,內容是:
page1 page1
可以看到,關聯的css、js靜態資源,都已被正確添加。
帶服務端的情況如果是帶服務端的應用,引用帶hash的資源文件將是另一個思路。
常見的做法是,為所有的靜態資源生成一個.json清單文件,然后在服務端讀取這個.json,然后把清單信息提供給模板文件,由此來正確地引用所需的靜態資源。
插件webpack-manifest-plugin或assets-webpack-plugin都可以幫助完成這一點。
服務端例子 - Spring Boot & Thymeleaf請看一個Spring Boot(1.5.3.RELEASE) & Thymeleaf(2.1)的例子。這里選擇webpack-manifest-plugin。
首先,在webpack的配置中加入這個插件:
{ plugins: [ new ManifestPlugin() ] }
執行webpack構建,即生成一個資源清單文件manifest.json(位置取決于webpack的output配置,這里是src/main/resources/static),它的內容是這樣:
{ "account/login.css": "account/login_style_f549ea0a.css", "account/login.js": "account/login_bundle_279af402.js" }
接下來,創建一個幫助類ResourceFormatter(名稱自擬):
public class ResourceFormatter{ private JsonNode resourceMap; public ResourceFormatter(){ ObjectMapper mapper = new ObjectMapper(); Resource resource = new ClassPathResource("static/manifest.json"); try { resourceMap = mapper.readValue(resource.getFile(), JsonNode.class); } catch (IOException e) { resourceMap = null; } } public String format(String originPath){ if(resourceMap != null && resourceMap.has(originPath)){ return "/" + resourceMap.get(originPath).asText(); } return "/" + originPath; } }
這個幫助類在初始化的時候就會讀取manifest.json,而在format()方法里則會利用清單信息對路徑進行轉換。
然后,把這個幫助類添加到模板引擎Thymeleaf內,包含兩步。
第一步,創建一個Dialect類:
public class ResourceDialect extends AbstractDialect implements IExpressionEnhancingDialect { public ResourceDialect() { super(); } @Override public String getPrefix() { return "resource"; } @Override public MapgetAdditionalExpressionObjects(IProcessingContext processingContext) { Map expressions = new HashMap<>(); expressions.put("resourceFormatter", new ResourceFormatter()); return expressions; } }
可以看到ResourceFormatter在這里被實例化并添加。
第二步,在Spring應用中注冊這個Dialect類:
@Configuration public class ThymeleafConfig { @Bean public ResourceDialect resourceDialect() { return new ResourceDialect(); } }
到此,就可以在Thymeleaf視圖模板文件中使用了。修改視圖文件如下(只包含修改的部分):
最后,啟動服務,訪問該頁,可以看到最終的輸出信息:
這就是我們要的帶hash的文件了。
此外,關于如何在Spring Boot中引入webpack,可以參考這個spring-boot-angular2-seed。
服務端例子 - Koa看完了一個傳統Java應用的例子,再來看看現代的Node應用。[Koa]Koa是簡潔的Node服務端框架,在它的基礎上引用帶hash的資源文件,也是同樣的思路。
首先,同樣是在webpack配置中加入webpack-manifest-plugin。
運行webpack構建生成manifest.json,內容大概會像這樣:
{ "page1.css": "page1/style_0b5ab6ef.css", "page1.js": "page1/bundle_0f33bdc8.js", "page1potofu.jpg": "page1/potofu_26766d43.jpg" }
然后,讀取這個json,為Koa(通過ctx.state)添加一個資源路徑轉換的幫助方法:
import manifest from "./public/manifest.json"; app.use(async(ctx, next) => { ctx.state.resourceFormat = (originPath) => { if (originPath in manifest) { return "/" + manifest[originPath]; } return "/" + originPath; }; await next(); });
最后,在視圖模板(這里的模板引擎是ejs)內,引用所需的靜態資源:
">
到此,Koa的例子就完成了。
結語帶hash的文件是現在web啟用緩存來提升性能比較建議的形式,如果你也有類似的生產環境優化的需要,很推薦你也試試。
(重新編輯自我的博客,原文地址:http://acgtofe.com/posts/2017...)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84137.html
摘要:所有的這些都是的功勞。默認為根據自己的指定的模板文件來生成特定的文件。最終在文件夾內會生成一個和文件。屬性值為文件所在的路徑名。默認值為不對生成的文件進行壓縮。選項的作用主要是針對多入口文件。不用說,按照不同文件的依賴關系來排序。 本文只在個人博客和 SegmentFault 社區個人專欄發表,轉載請注明出處 個人博客: https://zengxiaotao.github.io ...
摘要:默認不對文件進行壓縮。中集成的,生成模板文件壓縮配置,有很多配置項,這些配置項就是的壓縮選項值。給生成的文件尾部添加一個值。錯誤信息是否寫入文件。默認在文件中引用哪些文件用于多入口文件時。 title 生成頁面的titile元素 filename 生成的html文件的文件名。默認index.html,可以直接配置帶有子目錄 //webpack.config.js ... plugins...
一、HtmlWebpackPlugin使用: npm install html-webpack-plugin --save-dev 解釋:這個插件是簡化創建生成html(h5)文件用的,如果你引入的文件帶有hash值的話,這個尤為的有用,不需要手動去更改引入的文件名! 默認生成的是index.html,基本用法為: var HtmlWebpackPlugin = require(html-webp...
摘要:關于模板的有好幾種。一次安裝所有的大家可以了解一些的用法把編譯成。安裝參考文檔功能將源文件遷移到指定的目錄,返回新的文件路徑。安裝用法它會將所有的入口中引用的移動到和頁面對應的獨立分離的文件。 webpack是需要自己編寫自己需要的一個配置對象,取決你如何使用webpack,下面指定了所有的可用的配置選項。參考文檔:https://doc.webpack-china.org... we...
摘要:還記得我們上文中的文件嗎那里面的標簽還是寫死的文件,那么怎么把他們變成動態的文件,這個動態生成的文件會動態引入我們打包后生成的文件呢,我們可以使用插件,首先安裝這個插件,好的,接下來就開始用這個插件了官方參考文檔插件通用用法 還記得我們上文中的index.html文件嗎? 那里面的script標簽還是寫死的index.bundle.js文件,那么怎么把他們變成動態的index.html...
閱讀 3569·2021-11-15 11:36
閱讀 1060·2021-11-11 16:55
閱讀 694·2021-10-20 13:47
閱讀 2993·2021-09-29 09:35
閱讀 3428·2021-09-08 10:45
閱讀 2554·2019-08-30 15:44
閱讀 849·2019-08-30 11:10
閱讀 1428·2019-08-29 13:43