Vue 2.x + Webpack 3.x + Nodejs 多頁面項目框架(上篇——純前端多頁面)


Vue 2.x + Webpack 3.x + Nodejs 多頁面項目框架(上篇——純前端多頁面)

@(HTML/JS)

一般來說,使用vue做成單頁應用比較好,但特殊情況下,需要使用多頁面也有另外的好處。例如手Q的多webview架構,新開頁面有利於ios右划返回,也避免了返回時頁面的刷新。
所以,這里我們探討一下如何配置實現多頁面的項目框架。這里是開篇,先以最簡單的純前端多頁面為例入手,最終目標是完成Node.js多頁面直出+前后端同構的架構。

本文源代碼:https://github.com/kenkozheng/HTML5_research/tree/master/Vue-Multipages-Webpack3

本文目錄,也是實現純前端多頁面的步驟

  • vue-cli創建框架
  • 分析原型項目配置
  • 多頁面化改造

1 利用vue-cli搭建基本的框架

vue-cli是官方提供的腳手架工具,快速建立原型項目。

  • 安裝vue-cli:npm i -g vue-cli
  • 初始化項目:vue init <template-name> <project-name>

這里我選擇最簡單的template:webpack-simple。先創建項目目錄,然后在目錄內運行vue init webpack-simple,一路yes下去

然后,我們會得到這樣的目錄結構:
!

  • babelrc是babel的配置文件,詳細看babel自身的介紹
  • editorconfig控制編輯器的文字樣式之類的,可以刪掉
  • gitignore是git的配置
  • index.html就是單頁面的html
  • webpack.config.js已經區分了開發環境還是生產環境,生產環境加上uglify混淆
  • src目錄中包括了頁面的vue單文件(組件)和主入口main.js

2 運行分析原型項目

vue-cli把project.json、webpack配置還有npm腳本都准備好了,很贊。我們只需要兩步即可運行項目

    # 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熱更新全家桶,非常方便。
不過,我們需要看懂里邊所有源碼,才能進行下一步的操作。

>.babelrc

細節的配置很多,原型項目使用了env這個插件,並設置module相關的語法不轉義(留給webpack處理)

    ["env", { "modules": false }]

>webpack.config.js

  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需要重點區分一下。

  • path指的是打包后輸出的文件目錄
  • publicPath指的是path中生成的文件,對應的外網訪問地址,需要根據最終發布后項目實際如何部署來填寫,開發和生產兩個環境可能不一樣路徑。例如打包了一個圖片放到./dist/img1.jpg,那么響應js中的引用路徑變成/dist/img1.jpg。兩個參數要配合好。
    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

>App.vue和index.html

這兩個就是很基本的vue功能了。需要關注的是,現在只有一個index.html,而且index.html的功能比較單一純粹引入js。做多頁面時,html如何復用,是需要考慮的問題。

3 多頁面改造

了解了原型項目的功能,接下來需要做的事情包括:

  • 建立多頁面項目目錄,創建多個vue
  • webpack多entry配置
  • 復用html/自動生成html
  • 實際項目的一些優化

>創建多頁面

如圖所示

>webpack多entry配置

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映射。

>自動化生成html

因為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
    );

4運行起來

下載代碼: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看看吧


下篇:多頁面VueSSR+熱更新Server


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM