摘要:配置完成后就可以使用來打包代碼了。值得注意的是會刪除所有無作用代碼也就是說那些包裹在這些全局變量下的代碼塊都會被刪除這樣就能保證這些代碼不會因發布上線而泄露。默認會從項目的根目錄下引入這些文件。
命令使用
npm install webpack -g 作為全局安裝, 在任意目錄使用 npm install webpack --save-dev 作為項目依賴安裝 npm init 創建package.json npm install webpack-dev-server --save-dev 使用webpack-dev-server啟動服務器 webpack --progress -colors 讓編譯的輸出內容帶有進度和顏色 webpack --watch 如果不想每次修改模塊后都重新編譯, 那么可以啟動監聽模式。 開啟監聽模式后, 沒有變化的模塊會在編譯后緩存到內存中, 而不會每次都被重新編譯, 所以監聽模式的整體速度是很快的 webpack --display-error-details 用來打印錯誤詳情 npm install xxx-loader --save-dev 安裝多個加載器: npm install babel-core babel-preset-es2015 babel-preset-react npm webpack --config webpack.config.js 執行打包命令 npm start 啟動開發模式下的server npm run start:prod 啟動生產模式的server npm run build 打包生產模式的代碼 npm run lint: eslint 代碼檢查 npm run lint:watch: eslint 監視 npm run remove:build 刪除dist目錄 npm run clean:build 清除dist目錄 // 調用webpack webpack 開發環境下編譯 webpack -p 產品編譯及壓縮 webpack --watch 開發環境下持續的監聽文件變動來進行編譯 webpack -d 引入source maps配置文件
webpack.config.dev.js: 開發模式相關配置 webpack.config.prod.js: 生產模式相關配置 server.js: 配置本地的server(包含dev server和prod server) 將server部分分離到一個多帶帶到的文件配置 package.json
//webpack.config.dev.js var webpack = require("webpack"); var path = require("path"); var config = { // 入口文件配置 entry: { path.resolve(__dirname, "app/index.js"); }, // 文件輸出配置 output: { path: path.resolve(_dirname, "build"), filename: "bundle.js", publicPath: "/" }, // 插件項 plugins: [], // 加載器配置 module: { loaders: [ { test: /pattern/, loader: "xxx-loader", exclude: /dir/, query: { presets: ["react"] } }, { test: /.(png|jpg)$/, loader: "url-loader?limit=8192" // 內聯的base64的圖片地址, 圖片要小于8k, 直接的url的地址則不解析 } ] }, // 其他解決方案配置 resolve: { extensions: ["", ".js", ".json"], alias: {} }, watch: true }; module.exports = config;
webpack.server.js var webpack = require("webpack"); var webpackServer = require("webpack-dev-server"); var config = require("./webpack.config.dev.js"); var compiler = webpack(config); var server = new webpackDevServer(compiler, { contentBase: "./app", historyApiFallback: true, hot: true, //熱啟動 inline: true, // 監控js變化 stats: { color: true } }); config.entry.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server"); server.listen(8080, "localhost", function(err) { if(err) { console.log(err); } console.log("Listening at localhost:8080..."); }); "script": { "start": "node server.js" }配置詳解
entry: 入口, 定義要打包的文件 output: 出口, 定義打包輸出的文件;包括路徑, 文件名,還可能有運行時的訪問路徑(publicPath)參數 module: webpack將所有的資源都看做是模塊, 而模塊就需要加載器; |---- loaders: 主要定義一些loaders, 定義哪些后綴名的文件應該用哪些loader |-------- test: 匹配文件后綴, 檢測哪些文件需要此loader, 是一個正則表達式 |-------- exclude: 忽略哪些文件 |-------- query: 參數 (或直接寫于loader如: loader: "url-loader?limit=8192") |------------ presets: resolve: 其他解決方案配置 |---- extensions: 忽略文件擴展名, require文件時可直接使用require("file"),而非帶后綴如require("file.js") |-------- alias: 模塊別名定義,方便后續直接飲用別名無需多寫長地址, 后續直接require(key) plugins: 定義一些額外的插件 watch: 值為boolean, 監聽文件變化配置生產環境
開發環境: webpack.config.dev.js 需要日志輸出, sourcemap, 錯誤報告等 生產環境: webpack.config.prod.js 需要做代碼壓縮, 對文件名進行hash處理等區分環境
使用DefinePlugin設置環境變量, 根據設置的環境變量決定是否打包壓縮及啟動dev server或prod server
plugins: [ new webpack.DefinePlugin({ "process.evn.NODE_ENV": JSON.stringify("production") }); ]
判斷當前是否是生產環境
var isProduction = function() { return process.env.NODE_ENV === "production"; } output: { path: path.resolve(isProduction ? "__build" : "./assets/"), filename: isProduction ? "[name].js" : "./assets/js/[chunkhash:8].[name].min.js", chunkFilename: isProduction ? "[chunkhash:8].chunk.js" : "./assets/js/[chunkhash:8].chunk.min.js", publicPath: isProduction ? "/__build/" : "http://cdn.site.com/" }代碼壓縮
new webpack.optimizeUglifyJsPlugin({ compress: { warnings: false } });添加Hash緩存
對于沒有修改的文件, 從緩存中獲取文件, 對于已經修改的文件, 不要從緩存中獲取
output: { //chunkhash 默認16位, 可自定義配置 filename: "[chunkhash:8].bundle.js" }自動生成頁面
文件名帶上hash值后, 這個值在每次編譯的時候都會發生變化,都需要在 html 文件里手動修改引用的文件名,這種重復工作很瑣碎且容易出錯, 這里我們可以使用 html-webpack-plugin 來幫我們自動處理這件事情, 用來簡化創建服務于webpackbundle的HTML文件
解決方案: 在項目目錄下建一個index.tpl.html作為鉤子
My APP
在webpack.config.dev.js和webpack.config.prod.js添加配置代碼, 即可生成相應的index.html
plugins: [ new HtmlWebpackPlugin({ template: "app/index.tpl.html", inject: "body", filename: index.html }) ]加載器 js處理
babel-loader: 轉換JSX babel-core: babel核心包 babel-preset-react babel-preset-es2015
loaders:[ { loaders: "xxx-loader", query: { resets:["react", "es2015"] } } ]css處理
style-loader css-loader less-loaderimg處理
url-loader 可以根據自定義文件大小或者轉化為 base64 格式的 dataUrl, 或者多帶帶作為文件, 也可以自定義對應的hash 文件名 file-loader 默認情況下會根據圖片生成對應的 MD5hash 的文件格式 image-webpack-loader 提供壓縮圖片的功能
加載babel-loader需要配置query參數
loaders:[ { test: /.(jpe?g|png|gif|svg)$/i, loaders: [ // 當內容size小于8KB時, 會自動轉成base64的方式內嵌進去, 這樣可以減少一個HTTP的請求 // 當圖片大于8KB時, 則會在img/下生成壓縮后的圖片, 命名是[hash:8].[name].[ext]的形式 // hash:8的意思是取圖片內容hashsum值的前8位, // 這樣做能夠保證引用的是圖片資源的最新修改版本, 保證瀏覽器端能夠即時更新 "url?limit=8192&name=img/[hash:8].[name].[ext]", // 圖片壓縮 "image-webpack" ] } ]
loaders:[ { test: /.(jpe?g|png|gif|svg)$/i, loaders: [ // 生成md5 hash格式的文件名 "file?hash=sha512&digest=hex&name=[hash].[ext]", // 圖片壓縮 "image-webpack" ] } ]插件
plugins: [definPlugin, bannerPlugin, uglifyJsPlugin...]設置環境變量
var definPlugin = new webpack.DefinePlugin({ "process.env": { NODE_ENV: JSON.stringify("production") } // feature flags: 在開發環境(例如日志)活內部測試環境(例如沒有發布的新功能)中使用 // __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || "true")), // __PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || "false")) });給輸出的文件頭部添加注釋信息
var bannerPlugin = new webpack.BannerPlugin("This is test!");JS混淆
var uglifyJsPlugin = new webpack.optimize.UglifyJsPlugin({ mangle: { // 配置以下列表, 在混淆代碼時, 以下配置的變量, 不會被混淆 except: ["$super", "$", "exports", "require"] } });壓縮JS
var minChunkSizePlugin = new webpack.optimize.MinChunkSizePlugin({ compress: { warnings: false } });壓縮React
var definPlugin = new webpack.DefinePlugin({ "process.env": { NODE_ENV: JSON.stringify("production") } });加載jQuery
new webpack.ProvidePlugin({ $: "jquery" });公共模塊提取
new webpack.optimize.CommonsChunkPlugin({ name: "vendors", // 將公共模塊提取, 生成名為`vendors`的chunk chunks: ["index","list","about"], //提取哪些模塊共有的部分 minChunks: 3 // 提取至少3個模塊共有的部分 });多帶帶使用link標簽加載css并設置路徑
new ExtractTextPlugin("css/[name].css"), // 相對于output配置中的publickPath自動生成html文件, 模板生成的相關配置, 每個對于一個頁面的配置, 有幾個寫幾個
new HtmlWebpackPlugin({ //根據模板插入css/js等生成最終HTML favicon: "./src/img/favicon.ico", //favicon路徑, 通過webpack引入同時可以生成hash值 filename: "./view/index.html", //生成的html存放路徑, 相對于path template: "./src/view/index.html", //html模板路徑 inject: "body", //js插入的位置, true/"head"/"body"/false hash: true, //為靜態資源生成hash值 chunks: ["vendors", "index"], //需要引入的chunk, 不配置就會引入所有頁面的資源 minify: { //壓縮HTML文件 removeComments: true, //移除HTML中的注釋 collapseWhitespace: false //刪除空白符與換行符 } });
new HtmlWebpackPlugin({ //根據模板插入css/js等生成最終HTML favicon: "./src/img/favicon.ico", //favicon路徑, 通過webpack引入同時可以生成hash值 filename: "./view/list.html", //生成的html存放路徑, 相對于path template: "./src/view/list.html", //html模板路徑 inject: true, //js插入的位置, true/"head"/"body"/false hash: true, //為靜態資源生成hash值 chunks: ["vendors", "list"], //需要引入的chunk, 不配置就會引入所有頁面的資源 minify: { //壓縮HTML文件 removeComments: true, //移除HTML中的注釋 collapseWhitespace: false //刪除空白符與換行符 } });其它插件
new webpack.HotModuleReplacementPlugin() // 熱加載 HotModuleReplacementPlugin() // 代碼熱替換 NoErrorsPlugin() // 報錯但不退出webpack進程 OpenBrowserPlugin() // 自動打開瀏覽器webpack使用 分析多個模塊的公用代碼提取并多帶帶打包
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin("common.js"); module.exports = { entry: { page1: "./main1.js", page2: "./main2.js" }, output: { path: "build", filename: "[name].js" }, plugins: [ commonsPlugin ] }文件引用忽略擴展名配置
如果你希望在require文件時省略文件的擴展名, 只需要在webpack.config.js中添加 resolve.extensions 來配置。
// webpack.config.js module.exports = { entry: "./main.js", output: { filename: "bundle.js" }, module: { loaders: [ { test: /.coffee$/, loader: "coffee-loader" }, { test: /.js$/, loader: "babel-loader", query: { presets: ["es2015", "react"] } } ] }, resolve: { // 現在你require文件的時候可以直接使用require("file"), 不用使用require("file.coffee") extensions: ["", ".js", ".json", ".coffee"] } };css樣式和圖片的加載
首先你需要用require()去加載你的靜態資源(named as they would with node"s require()):
require("./bootstrap.css"); require("./myapp.less"); var img = document.createElement("img"); img.src = require("./glyph.png");
當你require了CSS(less或者其他)文件, webpack會在頁面中插入一個內聯的, 去引入樣式。當require圖片的時候, bundle文件會包含圖片的url, 并通過require()返回圖片的url。
但是這需要你在webpack.config.js做相應的配置(這里還是使用loaders)
// webpack.config.js module.exports = { entry: "./main.js", output: { path: "./build", // 圖片和js會放在這 publicPath: "http://mycdn.com/", // 這里用來生成圖片的地址 filename: "bundle.js" }, module: { loaders: [ { test: /.less$/, loader: "style-loader!css-loader!less-loader" }, // 用!去鏈式調用loader { test: /.css$/, loader: "style-loader!css-loader" }, { test: /.(png|jpg)$/, loader: "url-loader?limit=8192" // 內聯的base64的圖片地址, 圖片要小于8k, 直接的url的地址則不解析 } ] } };功能標識(Feature flags)
項目中有些代碼我們只為在開發環境(例如日志)或者是內部測試環境(例如那些沒有發布的新功能)中使用, 那就需要引入下面這些魔法全局變量(magic globals):
if (__DEV__) { console.warn("Extra logging"); } // ... if (__PRERELEASE__) { showSecretFeature(); }
同時還要在webpack.config.js中配置這些變量, 使得webpack能夠識別他們。
// webpack.config.js // definePlugin 會把定義的string 變量插入到Js代碼中。 var definePlugin = new webpack.DefinePlugin({ __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || "true")), __PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || "false")) }); module.exports = { entry: "./main.js", output: { filename: "bundle.js" }, plugins: [definePlugin] };
配置完成后, 就可以使用 BUILD_DEV=1 BUILD_PRERELEASE=1 webpack來打包代碼了。
值得注意的是, webpack -p 會刪除所有無作用代碼, 也就是說那些包裹在這些全局變量下的代碼塊都會被刪除, 這樣就能保證這些代碼不會因發布上線而泄露。
如果你有兩個頁面:profile和feed。如果你希望用戶訪問profile頁面時不加載feed頁面的代碼, 那就需要生成多個bundles文件:為每個頁面創建自己的“main module”(入口文件)。
// webpack.config.js module.exports = { entry: { Profile: "./profile.js", Feed: "./feed.js" }, output: { path: "build", filename: "[name].js" // name是基于上邊entry中定義的key } };
在profile頁面中插入。feed也一樣。
優化通用代碼Feed和Profile頁面存在大量通用代碼(比如React、公共的樣式和組件等等)。webpack可以抽離頁面間公共的代碼, 生成一個公共的bundle文件, 供這兩個頁面緩存使用:
// webpack.config.js var webpack = require("webpack"); var commonsPlugin = new webpack.optimize.CommonsChunkPlugin("common.js"); // 引入插件 module.exports = { entry: { Profile: "./profile.js", Feed: "./feed.js" }, output: { path: "build", filename: "[name].js" // 為上面entry的key值 }, plugins: [commonsPlugin] };
在上一步引入自己的bundle之前引入
異步加載雖然CommonJS是同步加載的, 但是webpack也提供了異步加載的方式。這對于單頁應用中使用的客戶端路由非常有用。當真正路由到了某個頁面的時候, 它的代碼才會被加載下來。
指定你要異步加載的 拆分點。看下面的例子
if (window.location.pathname === "/feed") { showLoadingState(); require.ensure([], function() { // 這個語法痕奇怪, 但是還是可以起作用的 hideLoadingState(); require("./feed").show(); // 當這個函數被調用的時候, 此模塊是一定已經被同步加載下來了 }); } else if (window.location.pathname === "/profile") { showLoadingState(); require.ensure([], function() { hideLoadingState(); require("./profile").show(); }); }
剩下的事就可以交給webpack, 它會為你生成并加載這些額外的 chunk 文件。
webpack 默認會從項目的根目錄下引入這些chunk文件。你也可以通過 output.publicPath來配置chunk文件的引入路徑
// webpack.config.js output: { path: "/home/proj/public/assets", // webpack的build路徑 publicPath: "/assets/" // 你require的路徑 }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85847.html
摘要:引言最近在學習,發現好多知識點,之前一點都沒有接觸過,如等等。使用本地安裝,會存于文件夾內與屬性內,更方便項目文件遷移以及協同開發等情況。 引言 最近在學習webpack,發現好多知識點,之前一點都沒有接觸過,如babel、core-js、browserslist等等。以前習慣了使用cli構建項目,很多東西不用考慮,拿來就用,這樣的碼農是不會有能力提升的,必須了解更多的知識點,才能成為...
摘要:新搭建的個人博客,本文地址學習筆記環境搭建本文的書寫環境為,之后會補充下的差異創建學習目錄初始化項目根據相關提示完善信息,入口文件安裝相關包,并且使用也就是支持,需要包,因為我之前做個一些相關項目,所以部分包已經全局安裝,比如等等,大家 新搭建的個人博客,本文地址:React學習筆記1:環境搭建 本文的書寫環境為mac,之后會補充windows下的差異 1、創建學習目錄 mkdir l...
摘要:前言在上一篇文章中我介紹了學習前的準備工作,下面開始的學習。目標一般我們接觸到的關于的文章,都是以解讀官方文檔為主,而且是針對單頁面項目的應用。我先在假設要做一個多頁面應用,該如何去通過打包。 前言 在上一篇文章中我介紹了學習webpack前的準備工作,下面開始webpack的學習。 *創建webpack-demo文件夾 $ mkdir webpack-demo $ cd webpac...
摘要:前言在上一篇文章中我介紹了學習前的準備工作,下面開始的學習。目標一般我們接觸到的關于的文章,都是以解讀官方文檔為主,而且是針對單頁面項目的應用。我先在假設要做一個多頁面應用,該如何去通過打包。 前言 在上一篇文章中我介紹了學習webpack前的準備工作,下面開始webpack的學習。 *創建webpack-demo文件夾 $ mkdir webpack-demo $ cd webpac...
摘要:運行該語句會執行如下步驟使用進行文件壓縮。設置環境變量,觸發某些包,以不同的方式進行編譯。在原始的源碼中執行查找和替換操作。等同于表示任何出現的地方都會被替換為。提供函數用來合并配置對象當文件小于限制,會返回。 選項 1.devtool:通過在瀏覽器調試工具(browser devtools)中添加元信息(meta info)增強調試。 2.resolve.alias:創建 impor...
閱讀 1399·2021-09-02 09:53
閱讀 2667·2021-07-29 13:50
閱讀 1715·2019-08-30 11:07
閱讀 1571·2019-08-30 11:00
閱讀 1450·2019-08-29 14:00
閱讀 1844·2019-08-29 12:52
閱讀 2560·2019-08-29 11:11
閱讀 3415·2019-08-26 12:23