最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

webpack4打包vue前端多頁面項目

 更新時間:2018年09月17日 14:40:56   作者:comWang  
這篇文章主要介紹了webpack4打包vue前端多頁面項目的相關(guān)知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下

之前一直用的腳手架,這次自己搭建webpack前端項目,花費了不少心思,于是做個總結(jié)。

1.用法

項目結(jié)構(gòu)如下:

project
 |- bulid          <!-- 這個目錄是自動生成的-->
    |- public
    |- css
    |- js
    |- page1.html       <!-- 插件生成的html文件-->
    |- page2.html       <!-- 插件生成的html文件-->
    ...
 |- public/         <!-- 存放字體、圖片、網(wǎng)頁模板等靜態(tài)資源-->
 |- src           <!-- 源碼文件夾-->
    |- components/
    |- css/
    |- js/
    |- page1.js        <!-- 每個頁面唯一的VUE實例,需綁定到#app-->
    |- page2.js        <!-- 每個頁面唯一的VUE實例,需綁定到#app-->
    ...
 |- package.json
 |- package-lock.json
 |- README.md

public文件夾存放一些靜態(tài)文件,src文件夾存放源碼。每個頁面通過一個入口文件(page1.js,page2.js,..)生成vue實例,掛載到插件生成的html文件的#app元素上。

安裝依賴

$ npm install

進入開發(fā)模式

$ npm run start

瀏覽器會打開 http://localhost:3000 ,這時頁面一片空白,顯示 cannot get幾個字。不要慌,在url后面加上 /page1.html ,回車,便可看見我們的頁面。 這是因為我把開發(fā)服務(wù)器的主頁設(shè)置為 index.html ,而本例中頁面為 page1.html,page2.html,因此會顯示一片空白。

開發(fā)完成了,構(gòu)建生產(chǎn)版本:

$ npm run build

這會產(chǎn)生一個build/文件夾,里面的文件都經(jīng)過優(yōu)化,服務(wù)器響應(yīng)的資源,就是來自于這個文件夾。

2.介紹

2.1 webpack基礎(chǔ)配置

我們的開發(fā)分為生產(chǎn)環(huán)境和開發(fā)環(huán)境,因此需要有2份webpack的配置文件(可能你會想用env環(huán)境變量,然后用3目運算符根據(jù)env的值返回不同值。然而這種方法在webpack導(dǎo)出模塊的屬性中無效,我試過~~~)。這里我們拆分成3個文件,其中 webpack.common.js 是常規(guī)的配置,在兩種環(huán)境下都會用到, webpack.dev.js 和 webpack.prod.js 則是在2種環(huán)境下的特有配置。這里用到 webpack-merge 這個包,將公共配置和特有配置進行合成。

webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const devMode = process.env.NODE_ENV !=='production';
// 需要被打包入口文件數(shù)組
// 數(shù)組元素類型 {string|object}
// string:將以默認(rèn)規(guī)則生成bundle
// object{filename|title|template} 生成的bundle.html的文件名|title標(biāo)簽內(nèi)容|路徑 /public 下的模板文件(需指定文件后綴)
const entryList = [
  'page1',
  'page2',
];
/**
 * @param {array} entryList
 * @param {object} option:可選 要手動配置的內(nèi)容
 */
const createEntry = (list = [], option = {}) => {
  const obj = {};
  list.forEach((item) => {
    const name = item.filename ? `./js/${item.filename}` : `./js/${item}`;
    obj[name] = path.resolve(__dirname, './src', `./${item}.js`);
  });
  return Object.assign(obj, option);
};
module.exports = {
  entry: createEntry(entryList),
  output: {
    path: path.resolve(__dirname, './build'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
      {
        test: /\.vue$/,
        use: 'vue-loader',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'public/fonts/[name].[ext]',
          },
        },
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'public/images/[name].[ext]',
          },
        },
      },
    ],
  },
  plugins: createPluginInstance(entryList).concat([
    // vue SFCs單文件支持
    new VueLoaderPlugin(),
  ]),
};

這里我們沒有進行css文件的配置,是因為生產(chǎn)環(huán)境下需要優(yōu)化、提取,所以在另外2個文件分別配置。

webpack.dev.js
const webpack = require('webpack');
const path = require('path');
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  output: {
    filename: '[name].js',
    chunkFilename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        use: [
          'vue-style-loader',
          'css-loader', 
          'postcss-loader',
          'less-loader'
        ],
      },
    ],
  },
  resolve: { alias: { vue: 'vue/dist/vue.js' } },
});

vue分為開發(fā)版本和生產(chǎn)版本,最后一行是根據(jù)路徑指定使用哪個版本。

webpack.prod.js

const webpack = require('webpack');
const merge = require('webpack-merge');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'production',
  output: {
    filename: '[name].[contenthash].js',
    chunkFilename: '[name].[contenthash].js',
  },
  resolve: { alias: { vue: 'vue/dist/vue.min.js' } },
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        use: [
          MiniCssExtractPlugin.loader, 
          'css-loader', 
          'postcss-loader',
          'less-loader'
        ],
      },
    ],
  },

在production環(huán)境下,我們使用了哈希值便于緩存,以后往生產(chǎn)環(huán)境下添加其他資源都會如此。

2.2 解決文件輸出目錄

我們期待的build文件夾具有如下結(jié)構(gòu):

build
  |- css/
  |- js/
  |- page1.html
  |- page2.html
  ...

即文件按照類型放在一起,html文件直接放在該目錄下,可是我們上面的配置的輸出結(jié)果是混合在一起的。由于name屬性既可以是文件名,也可以是 /dir/a 之類帶有路徑的文件名,我們根據(jù)這個特點做出一些修改。

直接對output的輸出路徑更改

比如改為 build/js ,其他資源利用相對路徑比如 ../page1.html 進行修改。我一開始就這樣做的,但最終會導(dǎo)致開發(fā)服務(wù)器無法響應(yīng)文件的變化,因為他只能針對輸出目錄下的文件進行監(jiān)聽,該目錄之上的文件變化無能為力。

修改入口名稱

這也是我們的最終解決方案。將原來的文件名 page1 修改為 /js/page1 ,最終輸出的js文件便都會放在js文件夾里。在生產(chǎn)環(huán)境下我們通過 MiniCssExtractPlugin 這個插件提取js文件中的css,這是該插件的配置:

new MiniCssExtractPlugin({
      filename:'[name].[contenthash].css'
    })

這里的name就是當(dāng)初入口的名字,受到入口名稱更改的影響,上面最終會變成 js/page1.131de8553ft82.css ,并且該占位符[name]只在編譯時有效,這意味著無法用函數(shù)對該值進行處理。因此不能使用[name]占位符達到想要的目的,干脆只用[id]。

new MiniCssExtractPlugin({
      filename:'/css/[id].[contenthash].css'
    })

3.代碼分割

在webpack4中使用optimization.splitChunks進行分割.

//webpack.common.js
const path = require('path');
module.exports = {
  // ... 省略其他內(nèi)容
  optimization:{
    runtimeChunk:{
      name:'./js/runtime'
    },
    splitChunks:{
      // 避免過度分割,設(shè)置尺寸不小于30kb
      //cacheGroups會繼承這個值
      minSize:30000,
      cacheGroups:{
        //vue相關(guān)框架
        main:{
          test: /[\\/]node_modules[\\/]vue[\\/]/,
          name: './js/main',
          chunks:'all'
        },
        //除Vue之外其他框架
        vendors:{
          test:/[\\/]node_modules[\\/]?!(vue)[\\/]/,
          name: './js/vendors',
          chunks:'all'
        },
        //業(yè)務(wù)中可復(fù)用的js
        extractedJS:{
          test:/[\\/]src[\\/].+\.js$/,
          name:'./js/extractedJS',
          chunks:'all'
        }
        
      }
    }
  }
};

runtimeChunk包含了一些webapck的樣板文件,使得你在不改變源文件內(nèi)容的情況下打包,哈希值仍然改變,因此我們把他單獨提取出來,點這兒了解更多。 cacheGroups用于提取復(fù)用的模塊,test會嘗試匹配( 模塊的絕對路徑||模塊名 ),返回值為true且滿足條件的模塊會被分割。滿足的條件可自定義,比如模塊最小應(yīng)該多大尺寸、至少被導(dǎo)入進多少個chunk(即復(fù)用的次數(shù))等。默認(rèn)在打包前模塊不小于30kb才被會分割。

4.樹抖動

在package.json里加入

"sideEffects":["*.css","*.less","*.sass"]

該數(shù)組之外的文件將會受到樹抖動的影響——未使用的代碼將會從export導(dǎo)出對象中剔除。這將大大減少無用代碼。如果樹抖動對某些文件具有副作用,就把這些文件名放進數(shù)組以跳過此操作。css文件(包括.less,.sass)都必須放進來,否則會出現(xiàn)樣式丟失。

5. 插件的使用

5.1 clean-webpack-plugin

每次打包后都會生成新的文件,這可能會導(dǎo)致無用的舊文件堆積,對于這些無用文件自己一個個刪太麻煩,這個插件會在每次打包前自動清理。實際中,我們不想在開發(fā)環(huán)境下清理掉build命令生成的文件,因此只在生產(chǎn)環(huán)境使用了這個插件。

5.2 html-Webpack-plugin

我們的源碼目錄中并沒有html文件,打包后的多個html文件,就是我們用這個插件生成的。

//webpack.common.js
// ...省略上面已經(jīng)出現(xiàn)過的內(nèi)容
//每個html需要一個插件實例
//批量生成html文件
const createPluginInstance = (list = []) => (
  list.map((item) => {
    return new HtmlWebpackPlugin({
      filename: item.filename ? `${item.filename}.html` : `${item}.html`,
      template: item.template ? `./public/${item.template}` :       './public/template.html',
      title: item.title ? item.title : item,
      chunks: [
        `./js/${item.filename ? item.filename : item}`,
        './js/extractedJS',
        './js/vendors',
        './js/main',
        './js/runtime',
        './css/styles.css',
        devMode ? './css/[id].css' : './css/[id].[contenthash].css',
      ],
    });
  })
);

默認(rèn)會將所有的入口文件,代碼分割后的文件打包進一個html文件里,通過指定 chunks 屬性來告訴插件 只包含 哪些塊,或者exludeChunks指定不應(yīng)包含那些chunks。這里有個小問題,我們無法讓文件剛好只包含他需要的塊。若想不包含未使用的chunks,只能根據(jù)實際情況手動配置,用這個函數(shù)批量生成的文件,總會包含所有的公共打包文件。

5.3 mini-css-extract-plugin (prooduction)

該插件用于提取js文件中的css到單獨的css文件中。

//webpack.prod.js
//...省略其他內(nèi)容
plugins:[
    new CleanWebpackPlugin('build'), 
    // 提取css
    new MiniCssExtractPlugin({
      filename:'./css/[id].[contenthash].css'
    }),
    //優(yōu)化緩存
    new webpack.HashedModuleIdsPlugin()
  ] 

5.4 optimize-css-assets-webpack-plugin (production)

用于精簡打包后的css代碼,設(shè)置在配置optimization的minimizer屬性中,這將會覆蓋webpack默認(rèn)設(shè)置,因此也要同時設(shè)置js的精簡工具(這里我們用uglifyplugin插件):

optimization: {
    minimizer:[
     new UglifyJsPlugin({
      cache: true,
      parallel: true
     }),
     new OptimizeCSSAssetsPlugin()
    ]
  }

6.開發(fā)服務(wù)器、熱模塊替換 (development)

webpack.dev.js中增加如下內(nèi)容即可:

//...省略其他內(nèi)容
devServer:{
    index:'index.html',
    hot:true,
    contentBase:path.resolve(__dirname,'./build'),
    port:3000,
    noInfo:true
  },
plugins:[
    new webpack.HotModuleReplacementPlugin()
  ]

使用開發(fā)服務(wù)器可以在我們修改了源文件后自動刷新,因為是將數(shù)據(jù)放在內(nèi)存中,因此不會影響硬盤中build文件夾。熱模塊替換還需要在源文件做相應(yīng)修改。我們也為動態(tài)導(dǎo)入語法進行了相應(yīng)配置。

7.其他

public用于存放靜態(tài)資源,打包后也會在build/下創(chuàng)建一個同名文件夾,里面存放的是public會被使用到的資源。如果在.css文件里引用了public里的資源,如圖片,添加url的時候要使用絕對路徑:

<!-- src/css/page1.css -->
.bg-img {
  background-image:url(/public/images/1.jpg)
}

這樣通過 http/https 打開的時候就能正常使用,如果是以文件形式打開(比如打包后雙擊page1.html),會發(fā)現(xiàn)瀏覽器顯示無法找到資源。通過導(dǎo)入圖片作為變量引用( import name from path ),既可使用絕對路徑,也可使用相對路徑。

總結(jié)

以上所述是小編給大家介紹的webpack4打包vue前端多頁面項目,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 詳解Vue.js和layui日期控件沖突問題解決辦法

    詳解Vue.js和layui日期控件沖突問題解決辦法

    這篇文章主要介紹了詳解Vue.js和layui日期控件沖突問題解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 如何用vue-cli3腳手架搭建一個基于ts的基礎(chǔ)腳手架的方法

    如何用vue-cli3腳手架搭建一個基于ts的基礎(chǔ)腳手架的方法

    這篇文章主要介紹了如何用vue-cli3腳手架搭建一個基于ts的基礎(chǔ)腳手架的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Vue實現(xiàn)商品放大鏡效果

    Vue實現(xiàn)商品放大鏡效果

    這篇文章主要為大家詳細(xì)介紹了Vue實現(xiàn)商品放大鏡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • vue實現(xiàn)配置全局訪問路徑頭(axios)

    vue實現(xiàn)配置全局訪問路徑頭(axios)

    今天小編就為大家分享一篇vue實現(xiàn)配置全局訪問路徑頭(axios),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • Vue中渲染系統(tǒng)模塊的實現(xiàn)詳解

    Vue中渲染系統(tǒng)模塊的實現(xiàn)詳解

    想要實現(xiàn)一個簡潔版的Mini-Vue框架,應(yīng)該包含三個模塊:分別是:渲染系統(tǒng)模塊、可響應(yīng)式系統(tǒng)模塊、應(yīng)用程序入庫模塊,本文主要介紹的是渲染系統(tǒng)模塊的實現(xiàn),需要的可以參考一下
    2023-07-07
  • VUE3子表格嵌套分頁查詢互相干擾的問題解決方案

    VUE3子表格嵌套分頁查詢互相干擾的問題解決方案

    這篇文章主要介紹了VUE3子表格嵌套分頁查詢互相干擾的問題解決方案,如果不需要做子表格的分頁查詢,那么可以直接在主表格中嵌套子表格,本文給大家介紹兩種方式,需要的朋友可以參考下
    2024-01-01
  • vue?elementui?實現(xiàn)搜索欄子組件封裝的示例代碼

    vue?elementui?實現(xiàn)搜索欄子組件封裝的示例代碼

    這篇文章主要介紹了vue?elementui?搜索欄子組件封裝,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • vue axios 給生產(chǎn)環(huán)境和發(fā)布環(huán)境配置不同的接口地址(推薦)

    vue axios 給生產(chǎn)環(huán)境和發(fā)布環(huán)境配置不同的接口地址(推薦)

    這篇文章主要介紹了vue axios 給生產(chǎn)環(huán)境和發(fā)布環(huán)境配置不同的接口地址,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-05-05
  • vue如何使用笛卡爾積算法構(gòu)建sku表格

    vue如何使用笛卡爾積算法構(gòu)建sku表格

    這篇文章主要介紹了vue如何使用笛卡爾積算法構(gòu)建sku表格問題,具有很好的價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue2.x-使用防抖以及節(jié)流的示例

    Vue2.x-使用防抖以及節(jié)流的示例

    這篇文章主要介紹了Vue2.x-使用防抖以及節(jié)流的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-03-03

最新評論

南澳县| 石首市| 宜城市| 崇州市| 望都县| 九江市| 阜宁县| 从江县| 观塘区| 密云县| 休宁县| 大丰市| 乐清市| 民县| 贵港市| 察隅县| 麻栗坡县| 宣武区| 军事| 甘谷县| 湟中县| 昂仁县| 临邑县| 鄂尔多斯市| 突泉县| 天柱县| 抚远县| 积石山| 福鼎市| 惠水县| 定襄县| 武汉市| 镇原县| 三明市| 宜川县| 襄垣县| 临沂市| 嘉峪关市| 葫芦岛市| 犍为县| 马尔康县|