摘要:是目前使用最為火熱的打包工具,各大知名的框架類庫都用其打包,國內使用最近也火熱起來。但是坑也很多,比如說圖片,字體等文件的路徑。
webpack 是目前使用最為火熱的打包工具,各大知名的框架類庫都用其打包,國內使用最近也火熱起來。它在單頁應用和類庫打包上幫助許多人從代碼管理中解脫了出來,成為了當下風靡一時的打包工具。
但是坑也很多,比如說圖片,字體等文件的路徑。
剛開始用webpack的同學很容易掉進圖片打包這個坑里,比如打包出來的圖片地址不對或者有的圖片并不能打包進我們的目標文件夾里。明明在開發階段都是好好的,一但發布到線上,就出現各種404,
一般來說,webpack打包的SPA程序,發布到網站的根目錄下都不會出現太多問題,但是發布到網站的子目下,就會出現各種資源文件找不到的情況。
這種文件,我在以下這個知乎的帖子里曾經做過詳細的回答
知乎用戶:vuejs怎么在服務器部署?
似乎所有問題都解決了,但有一個問題沒有解決,就是如果我在css里引了了圖片資源,webpack并不能很好的處理這里面的資源路徑
比如我把spa部署在 https://www.wx2share.com/m/
“m”文件夾是網站下的一個子目錄,
如果我在開發的時候,寫了如下css代碼
.content { background: url("/static/img/1.jpg") }
首先,我們修改(tips:我的配置文件是通過vue-cli生成的)
build: { env: require("./prod.env"), index: path.resolve(__dirname, "../dist/index.html"), assetsRoot: path.resolve(__dirname, "../dist"), assetsSubDirectory: "static", assetsPublicPath: "/m/", //這里指定publicPath 的路徑為我子目錄文件名,一般默認為"/" productionSourceMap: true, },
webpack publicPath 參數是用來,幫助你為項目中的所有資源指定一個基礎路徑,一但設定值以后,所有代碼中通過requrie 或import 方式引入的資源文件,在build以后,都回指向類似 "/m/static/xxx.xx"
比如:
logo: require("@/assets/v.png")
編譯以后,
可以看到,webpack 已經正確的把資源文件的路徑里 加上了/m ,保證了資源文件引用正確,這里順便提一點,publicpath 還可以設置在cdn的url
如果 publicPath: "https://cdn.youdomin.com/" 這樣編譯以后,src=""https://cdn.youdomin.com//static/img/logo_small.f457a3f.png
這樣你只要把static整個文件夾托管的你的cdn上就可以了非常方便。但是publicPath 一定用絕對路徑,絕對路徑,絕對路徑(重要的事說3遍) 千萬不要用相對路徑,如果你把publicPath設為"./",哪你啟用路由以后,https://www.wx2share.com/m/ 這樣的url進入程序的,不會有問題,因為這個時候,static文件正好在當前目錄下,但是當你類似用這樣的網址來訪問的時候 ,https://www.wx2share.com/m/sh... 資源文件又找不到了,因為這個時候./的指向的目錄是
/m/show/static/ 很明顯你的資源文件全在 /m/static下,所以又404了。
上面的方法基本解決了大部分的問題,唯一不能解決的就是文章開頭提到的,css中引入的資源文件的問題了
通過publicpath的設置,并不到改變css中引用資源文件的路徑,上面實例代碼中的css編譯后,還是
.content { background: url("/static/img/1.jpg") }
是乎webpack 并不處理css中的文件路徑,這樣的結果就是發布以后頁面上所有通過css引入的資源文件全部不能正常顯示了。前段時間我采用了一個簡單又粗爆的方法來解決這個問題,哪就是,絕對不用css引入任何文件。當然你也可以手動修改webpack編譯過的文件,把通過查找替換 把/static 替換為/m/static 如果你不嫌累的慌。
最近又開始了一個新的SPA應用,引入了一個第三方css,里面好多通過css引入的圖片文件 ,讓我不得不下定決心來解決這個問題了
TIPS: 以下內容的配置文件修改全部是基于由vue-cli生成的配置文件,如果你是用自己寫的配置文件請注意區別!
我首先想到,如果開發的時候我就是指定在“m/”子目錄下,不就能解決大部分問題了,這樣和線上的根目錄文件對應了,buid以后就不會有哪么多問題 ,
第一步:修改dev模式上的publicPath
dev: { env: require("./dev.env"), port: 8082, autoOpenBrowser: true, assetsSubDirectory: "static", assetsPublicPath: "/m/", //把dev模式下的publicPath也設為 m proxyTable: {}, cssSourceMap: false } yarn run dev
以后,訪問 http://localhost:8082/m/ 結果好么,直接給我來了個 can not get /m/
但是如果我直接訪問http://localhost:8082/m/index.html 是可以的,而且功能基本正常,是就vue的router不起作用了,在瀏覽器地址欄里直接敲入 http://loalhost:8082/m/view/1 然后回車,這樣的地址就全部404了,看來是dev sever沒有把,所有鏈接從新定向到 /m/index.html上,但是publicPath設置是正確的了,現在要解決的問題就是,無論在瀏覽器地址欄里輸入什么網址,都讓它重定向到 /m/index.html 就可以解決所有問題了,
webpack 的dev sever 是什么,用什么來實現的,能過查看buid/dev-server.js
發現是用express 來實現web server,通過加載webpack-dev-middleware 來實現實時編譯,所有請求都轉發給它了,所以,在node_modules下找到它的源代碼,看了老半天,看不出所以然來,只能debug了,看它到底是怎么運作的,電腦上沒有調試的工具,只好,通過打log的方法來調試了。
function webpackDevMiddleware(req, res, next) { function goNext() { if(!context.options.serverSideRender) return next(); return new Promise(function(resolve) { shared.ready(function() { res.locals.webpackStats = context.webpackStats; resolve(next()); }, req); }); } if(req.method !== "GET") { return goNext(); } var filename = getFilenameFromUrl(context.options.publicPath, context.compiler, req.url); console.log(filename) //關鍵就是這里,只有filename不等于 false的時候才進入真正的處理階段 if(filename === false) return goNext(); //下面還有好多代碼,不粘貼了, 既然這里返回 false
我們進入 getFileNameFromUrl 這個函數看看,為什么會false
function getFilenameFromUrl(publicPath, outputPath, url) { var filename; console.log(publicPath, outputPath, url) //我在這里打了個log // localPrefix is the folder our bundle should be in var localPrefix = urlParse(publicPath || "/", false, true); var urlObject = urlParse(url); // publicPath has the hostname that is not the same as request url"s, should fail if(localPrefix.hostname !== null && urlObject.hostname !== null && localPrefix.hostname !== urlObject.hostname) { return false; } // publicPath is not in url, so it should fail if(publicPath && localPrefix.hostname === urlObject.hostname && url.indexOf(publicPath) !== 0) { return false; //就這里return false了 } // strip localPrefix from the start of url if(urlObject.pathname.indexOf(localPrefix.pathname) === 0) { filename = urlObject.pathname.substr(localPrefix.pathname.length); } if(!urlObject.hostname && localPrefix.hostname && url.indexOf(localPrefix.path) !== 0) { return false; } // and if not match, use outputPath as filename return querystring.unescape(filename ? pathJoin(outputPath, filename) : outputPath); }
看上面代碼,我在進入函數的頭部打了一個log,看看傳入的參數到底是什么
當我訪問 http://localhost:8082/m/ 的時候 控制臺里輸出
發現 publicPath, outputPath, url,三個參數的值分別為:
/m/ F:workspacewx2share-pwadist /index.html
終于發現
if(publicPath && localPrefix.hostname === urlObject.hostname && url.indexOf(publicPath) !== 0) {
return false; //就這里return false了 }
url.index.of(publicPath) !== 0 這一個條件成立了 相當于 "/index.html/".indexOf("/m/") 肯定不會===0 啊,
但是這個‘/index.html" 這個參數的值哪里來的,回到上一段代碼中,發現是req.url里傳過來的,
但我明明訪問的是/m/ 哪,req.url 應該等于 "/m/"啊,這是什么時候給重定向的呢,看來在這個之前,已經有過一次重定向了
回到dev-server.js文件,發現在,use devMiddlewarre 之前,還引入了一個connect-history-api-fallback的中間件,看來唯一能重定向的地方只有這里了,
app.use(require("connect-history-api-fallback")()); // 服務器部署 webpack 打包的靜態資源 app.use(devMiddleware); // 使用熱更新, 如果編譯出現錯誤會實時展示編譯錯誤 app.use(hotMiddleware);
打開connect-history-api-fallback的代碼,終于發現了
rewriteTarget = options.index || "/index.html"; logger("Rewriting", req.method, req.url, "to", rewriteTarget); req.url = rewriteTarget; next(); 這個的代碼,當你不作配置的時候,默認重定向到根目錄的/index.html上,找到原因了,修改就簡單了 // 處理 history API 的回退情況(如果在線上環境中,也需要服務器做相應處理) app.use(require("connect-history-api-fallback")({ index: "/m/index.html" }));
把options.index的值設為 /m/index.html 不就可以了吧,這樣所有的請求,都會轉發到/m/index.html了
再次打開http://localhost:8082/m/ 一切全部正常了,build以后,發現在線上,也完全正常,再也不會找不到css中引入的資源文件了
一個重點差點忘記提了
就是現在寫css代碼里,引入static文件中的文件,直接要寫加上publicPath的路徑,
就是原來寫成
.content { background: url("/static/img/1.jpg") }
要在編碼階段全部寫成
.content { background: url("/m/static/img/1.jpg") //直接帶上發布是的絕對路徑 }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89963.html
Vue應用部署到服務器的正確方式 很多時候我們發現辛辛苦苦寫的VueJs應用經過打包后在自己本地搭建的服務器上測試沒有什么問題,但真正放在服務器上后,會發現或多或少的問題,比如:頁面出現空白現象,獲取資源路徑不對等,我相信以VueJs為技術棧來進行前端開發的小伙伴或多或少都會遇到這樣的問題,我也遇到過,那現在我們就來一一解決這樣的問題。 如何打包 基于Vue-Cli,通過npm run build...
摘要:放置在目錄下或通過絕對路徑被引用。對于相關來說,我們推薦使用而不是直接鏈式指定。在不更改配置文件的情況下,前端頁面迭代發布,不需要重啟服務。 作者:gauseen 0. 關于 Vuejs 簡介:Vue (讀音 /vju?/,類似于 view) 是一套用于構建用戶界面的漸進式框架,易用、靈活、高效。 生態系統 項目 介紹 awesome-vue Vue.js 相關很棒的...
摘要:使用開發公眾號商城第篇記錄項目準備搭建,寫頁面遇到第問題以及總結,持續更新公司最近接了個商城項目,包括端商城微信公眾號網頁商城后臺管理系統。這幾天在做微信公眾號商城,又新接觸了很多東西。 使用vue開發公眾號商城 第1篇記錄項目準備、搭建,寫頁面遇到第問題以及總結,持續更新 公司最近接了個商城項目,包括PC端商城、微信公眾號網頁商城、后臺管理系統。這幾天在做微信公眾號商城,又新接觸了很...
摘要:使用開發公眾號商城第篇記錄項目準備搭建,寫頁面遇到第問題以及總結,持續更新公司最近接了個商城項目,包括端商城微信公眾號網頁商城后臺管理系統。這幾天在做微信公眾號商城,又新接觸了很多東西。 使用vue開發公眾號商城 第1篇記錄項目準備、搭建,寫頁面遇到第問題以及總結,持續更新 公司最近接了個商城項目,包括PC端商城、微信公眾號網頁商城、后臺管理系統。這幾天在做微信公眾號商城,又新接觸了很...
閱讀 998·2023-04-26 02:21
閱讀 2816·2021-09-24 09:47
閱讀 1607·2019-08-30 15:55
閱讀 2162·2019-08-30 14:01
閱讀 2319·2019-08-29 14:01
閱讀 2047·2019-08-29 12:46
閱讀 813·2019-08-26 13:27
閱讀 1932·2019-08-26 12:23