@(HTML/JS)javascript
通常來講,使用vue作成單頁應用比較好,但特殊狀況下,須要使用多頁面也有另外的好處。例如手Q的多webview架構,新開頁面有利於ios右劃返回,也避免了返回時頁面的刷新。
因此,這裏咱們探討一下如何配置實現多頁面的項目框架。這裏是開篇,先以最簡單的純前端多頁面爲例入手,最終目標是完成Node.js多頁面直出+先後端同構的架構。css
本文源代碼:https://github.com/kenkozheng/HTML5_research/tree/master/Vue-Multipages-Webpack3html
本文目錄,也是實現純前端多頁面的步驟前端
vue-cli
搭建基本的框架vue-cli是官方提供的腳手架工具,快速創建原型項目。vue
npm i -g vue-cli
vue init <template-name> <project-name>
這裏我選擇最簡單的template:webpack-simple。先建立項目目錄,而後在目錄內運行vue init webpack-simple
,一路yes下去java
而後,咱們會獲得這樣的目錄結構:
!node
vue-cli把project.json、webpack配置還有npm腳本都準備好了,很贊。咱們只須要兩步便可運行項目webpack
# install dependencies npm install # serve with hot reload at localhost:8080 npm run dev # build for production with minification npm run build
運行npm run dev就能夠啓動默認的在8080端口監聽的服務器,帶有webpack熱更新全家桶,很是方便。
不過,咱們須要看懂裏邊全部源碼,才能進行下一步的操做。ios
細節的配置不少,原型項目使用了env這個插件,並設置module相關的語法不轉義(留給webpack處理)git
["env", { "modules": false }]
entry: './src/main.js', output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'build.js' }
entry能夠爲數組或對象或單個字符串,指定須要打包的文件;
output指定打包後輸出的信息。這裏最好參考官方文檔,實在不行就看源碼,各類網上文章可能都會說錯,包括我這一篇。官方文檔:https://doc.webpack-china.org/concepts/output/
關鍵點是,filename能夠用[name].[hash:8]等關鍵字的方式實現根據entry輸入而動態變化的文件名,後續會用到。
path和publicPath須要重點區分一下。
module: { rules: [ { test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ], } ... { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } } ] }
再看看module,這裏從2.x開始就改了格式,一目瞭然,就是各類文件應該使用什麼loader去加載處理。
主要須要關心最後這個file-loader,name要跟以前publicPath配合好,除了寫文件名還能夠寫目錄,webpack會自動建立目錄存放文件。
resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' }, extensions: ['*', '.js', '.vue', '.json'] }, devServer: { historyApiFallback: true, noInfo: true, overlay: true }, performance: { hints: false }, devtool: '#eval-source-map'
resolve的alias目的是作一個別名映射,當代碼中出現vue$時,能夠動態替換爲對應的字符串。
devServer控制webpack自帶的熱更新服務器的行爲,例如修改一下端口。使用npm腳本運行:webpack-dev-server --open --hot
。須要注意的是,devserver使用memory-fs,並不直接寫文件系統。配合WriteFilePlugin能夠強制寫入。若是不使用devserver調試,例如fiddler替換,就須要強制寫入文件系統了。
performance能夠先略過
devtool是控制生成的源代碼source-map功能,按照默認便可,具體的使用原理簡單說,就是瀏覽器支持的混淆後代碼映射到源文件的映射表。
process.env.NODE_ENV === 'production' new webpack.optimize.UglifyJsPlugin({ sourceMap: true, compress: { warnings: false } })
最後判斷了環境變量,若是是生產發佈,再加上uglify插件。這裏的參數設置能夠參考uglify插件自己。
環境變量的設置,使用的是cross-env工具,在npm腳本中運行設置的cross-env NODE_ENV=production
這兩個就是很基本的vue功能了。須要關注的是,如今只有一個index.html,並且index.html的功能比較單一純粹引入js。作多頁面時,html如何複用,是須要考慮的問題。
瞭解了原型項目的功能,接下來須要作的事情包括:
如圖所示
var pages = ['page1', 'page2']; //能夠根據項目狀況,自動分析目錄文件生成 var entry = {}; pages.forEach(function (pageName) { entry[pageName] = `./src/pages/${pageName}/main.js`; }); ////////////// module.exports = { entry: entry, output: { path: path.resolve(__dirname, `./dist/`), publicPath: process.env.NODE_ENV === 'production' ? '/' : '/dist/', //發佈後在線訪問的url。dev模式下,使用的是express在當前項目根目錄啓動 filename: `[name].js` //'[name].[chunkhash].js', '[name].[hash:8].js' } ...
主要是filename使用了動態的配置方式,會根據entry的key映射。
由於index.html內容簡單,咱們不必每一個頁面都複製一份。而別人早就想到這個了,因此有了html-webpack-plugin
。
老規矩,npm install起來
而後,修改webpack配置
pages.forEach(function (pageName) { module.exports.plugins.push( new HtmlWebpackPlugin({ title: pageName, filename: `${pageName}.html`, template: `./src/pages/tpl.html`, chunks: [pageName], inlineSource: '.(js|css)$' // embed all javascript and css inline。結合HtmlWebpackInlineSourcePlugin纔有效果 }) ); });
根據pages數組的配置,自動建多個HtmlWebpackPlugin實例插到配置中。
顧名思義,配置起了比較簡單,詳情參考官網:https://github.com/jantimon/html-webpack-plugin
inlineSource是特殊的字段,後續再說。
至此,就能夠把項目跑起來了,dev模式下,webpack每次自動打包都會生成page1和page2。
全局共用css的打包
在頁面main.js中,直接import便可,最終會轉換爲注入到html的js代碼。
import '../../css/base.css'
圖片打包文件名管理
{ test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' //自動hash命名圖片等資源,並修改路徑。路徑須要根據項目實際狀況肯定。語法參考:https://doc.webpack-china.org/loaders/file-loader/ } }
每每圖片發佈後都是長緩存,那麼在文件名中加入hash作版本區分是個好方式。另外,使用獨立的目錄,更方便cdn設置緩存時間。
html、js、css打包到一塊兒,減小請求
多頁面決定了每一個頁面不會太大,對於目前的移動互聯網來講,打包在一塊兒的html會比多個js請求更快。
這咱們須要用到HtmlWebpackInlineSourcePlugin
,也就是剛纔提到的inlineSource字段。
module.exports.plugins.push( new HtmlWebpackInlineSourcePlugin() //內聯css、js。配合HtmlWebpackPlugin );
下載代碼:https://github.com/kenkozheng/HTML5_research/tree/master/Vue-Multipages-Webpack3
npm i npm run dev
瀏覽器訪問http://localhost:8088/dist/page1.html和http://localhost:8088/dist/page2.html看看吧