webpack手動搭建vue2.0環(huán)境

基礎常識:

查看版本號:

vue -V
webpack -v 查看當前版本

已有項目升級webpack到最新版:

刪除node_modules目錄
進入package.json文件修改版本號到最新
npm install --save-dev webpack

升級webpack到最新版:

刪除node_modules目錄
npm install --save-dev webpack
npm -v/cnpm -v

簡介:此項目為vue2.x 使用webpack4構建項目的文檔教程暇务,自我學習保存具壮。
前言:為了方便項目的存儲奏瞬,可以先在碼云上建個倉庫吸祟,git clone一下琉历,然后修改下.gitignore文件 將node_modules/ 和 /dist/ 加入舞萄,最好從其他項目中復制一份過來恩沽。

好了誊稚,正文開始:

1.npm init 生成 packge.json文件

image.png

2.安裝必要依賴

(1)npm i webpack webpack-cli webpack-dev-server webpack-merge --save-dev

image.png

webpack-cli: webpack中分離出來的
webpack-dev-server
webpack-merge

(2)npm i vue vue-router vuex --save

image.png

3.創(chuàng)建目錄結構

|--dist
|--build
    |--webpack.prod.js
    |--webpack.dev.js
    |--webpack.base.js
|--src
    |--index.js
    |--app.vue
    |--router.js
    |--store.js
    |--assets
    |--components
    |--views
|--index.html

4.安裝vue核心解析插件 npm i vue-loader vue-template-compiler --save-dev

5.安裝其他的loader

在同一個 test 下配置多個loader時,優(yōu)先處理的 loader 放在配置數(shù)組的后面
(1)必要的:

CSS 基礎 loader:
css-loader: "^1.0.0", // 加載.css文件
style-loader: "^0.21.0", //使用<style>將css-loader內(nèi)部樣式注入到我們的HTML頁面
file-loader// 解析圖片罗心,字體等
url-loader //設置上limit選項里伯,將小于limit的圖片轉編碼,大于limit的交給file-loader復制路徑來引用使用

注意:具體參考vue-webpack模板协屡,配置url-loader后不需要配置file-loader俏脊,但可在url-loader中添加name字段,file-loader會實現(xiàn)name字段內(nèi)容肤晓。文末會放上build文件夾下爷贫,三個配置文件的代碼。

npm i babel-core --save-dev
npm i @babel/core --save-dev
@babel/preset-env --save-dev // 是一個配置文件补憾,我們可以使用這個配置文件轉換 ES2015/ES2016/ES2017 到 ES5
babel-preset-env 這個是舊版本的

.babelrc文件:

{
  "presets": ["@babel/preset-env"]
}

npm i babel-loader --save-dev //可以把ES6語法轉為ES5語法
npm i html-webpack-plugin --save-dev //安裝 html 模板解析插件
npm i clean-webpack-plugin --save-dev //解決每次重新打包漫萄,dist 文件夾文件未清除

(2)選擇性的:
CSS 前處理 less 兩件套
"less": "^3.8.0",
"less-loader": "^4.1.0",
CSS 前處理 sass 兩件套
"node-sass": "^4.9.2",
"sass-loader": "^7.1.0",
CSS 后處理 postcss 兩件套
"postcss-loader": "^2.1.6",
"autoprefixer": "^9.1.0",
npm install mini-css-extract-plugin --save-dev //webpack4中分離CSS。插件來分離 css盈匾。

注意:這個插件應該只用在 production 配置中腾务,并且在loaders鏈中不使用 style-loader, 特別是在開發(fā)中使用HMR,因為這個插件暫時不支持HMR,具體看模板文件配置

npm install image-webpack-loader --save-dev //圖片壓縮
npm i optimize-css-assets-webpack-plugin --save-dev // css代碼壓縮削饵,優(yōu)化css結構岩瘦,利于網(wǎng)頁加載和渲染
npm i uglifyjs-webpack-plugin --save-dev // js代碼壓縮
npm i --save-dev cross-env 能跨平臺地設置及使用環(huán)境變量,不同平臺使用唯一指令窿撬,無需擔心跨平臺問題启昧。

總結一下loader的常用四種寫法:

use: [xxx, xxx]
use: [{loader: XXX}, {loader: XXX}]
use: [{
     loader: XXX,
     options: {}
}, 'XXX']
loader: [XXX, XXX]

loader的options配置項里面還可以放置loader,also plugins

常用的loader:

  • 處理樣式的:style-loader,css-loader,postcss-loader,sass-loader,less-loder
  • 處理es6的:babel-loader(要連同babel-core, babel-preset-env)一起用
  • 處理圖片的:file-loader, url-loader, image-webpack-loader

常用的plugin:

  • 壓縮js:uglifyjs-webpack-plugin
  • 合并&壓縮css: mini-css-extract-plugin劈伴,optimize-css-assets-webpack-plugin
  • 清除目錄:clean-webpack-plugin
  • 生成html:html-webpack-plugin
  • postcss相關的:postcss-plugin-px2rem密末,postcss-preset-env,postcss-sprites跛璧,autoprefixer
  • webpack自帶的方法:webpack.ProvidePlugin等

build文件夾下的配置文件:

webpack.base.js

// webpack.base.js
// 存放 dev 和 prod 通用配置
const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
//mini-css-extract-plugin插件應該只用在 production 配置中严里,并且在loaders鏈中不使用 style-loader, 特別是在開發(fā)中使用HMR,因為這個插件暫時不支持HMR
const devMode = process.env.NODE_ENV !== 'production';
//console.log(process.env.NODE_ENV,"devMode--------------")
//webpack4 分離css插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
//使用 WEBPACK_SERVE 環(huán)境變量檢測當前是否是在 webpack-server 啟動的開發(fā)環(huán)境中
//const dev = Boolean(process.env.WEBPACK_SERVE)
// 使用happypack---加速webpack打包
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({
  size: os.cpus().length
});


module.exports = {
  entry: './src/index.js', //入口
  /*
  配置各種類型文件的加載器追城,稱之為 loader
  webpack 當遇到 import ... 時刹碾,會調(diào)用這里配置的 loader 對引用的文件進行編譯
  */
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        // 正則匹配所有以.css結尾的文件
        // 它會應用到普通的 `.css` 文件
        // 以及 `.vue` 文件中的 `<style>` 塊
        test: /\.(sa|sc|c)ss$/,
        // 使用css-loader和style-loader依次對css文件進行處理
        /*
        先使用 css-loader 處理,返回的結果交給 style-loader 處理座柱。
        css-loader 將 css 內(nèi)容存為 js 字符串教硫,并且會把 background, 
        @font-face 等引用的圖片叨吮,字體文件交給指定的 loader 打包,
        */
        // 按照數(shù)組中從后往前的順序
        use: [
          devMode?'vue-style-loader':{
            loader:MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../'
            }
          },
          /***
            **還沒有嘗試css-loader的url屬性是否可行
          ***/
          /* {
            loader: 'css-loader',
            options: {
              url: false, // css中加載圖片的路徑將不會被解析 不會改變
              minimize: true,   //
              importLoaders: 1
            }
          }, */
          'css-loader',
          'sass-loader'
        ]
      },
      // 圖片處理
      {
        //test: /\.(gif|png|jpe?g|svg)$/i,
        test: /\.(png|jpg|jpeg|gif|svg|svgz)(\?.+)?$/,
        //enforce: 'pre',  // 這會應用該 loader瞬矩,在其它之前
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192, //單位Bytes茶鉴,即轉換8KB以下的圖
              // 當圖片大于8192時,分離圖片至imgs文件夾
              // [ext]是占位符 表示文件的后綴名
              /* name: devMode ? "img/[name].[ext]" : "img/[hash:6][name].[ext]" */
              name: devMode ? "[name].[ext]" : "[hash:6][name].[ext]",//和注釋那行的效果一樣
              publicPath: "./img/",
              outputPath: "img/"
              /* fallback: ['file-loader','image-webpack-loader'],
              quality: 85 */
            }
          },
          // 圖片壓縮
          //'file-loader',
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: '65-90',
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            }
          }
        ]
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 8192,
          name: devMode ? "fonts/[name].[ext]" : "fonts/[hash:3][name].[ext]"
        }
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/
        /* exclude: __dirname + 'node_modules',
        include: __dirname + 'src',
        options: {
          presets: ['env']
        } */
      },
      {
        test: /\.js$/,
        //把對.js 的文件處理交給id為happyBabel 的HappyPack 的實例執(zhí)行
        loader: 'happypack/loader?id=happyBabel',
        //排除node_modules 目錄下的文件
        exclude: /node_modules/
      }
      


    ]
  },
  /*
  配置 webpack 插件
  plugin 和 loader 的區(qū)別是景用,loader 是在 import 時根據(jù)不同的文件名涵叮,匹配不同的 loader 對這個文件做處理,
  而 plugin, 關注的不是文件的格式伞插,而是在編譯的各個階段割粮,會觸發(fā)不同的事件,讓你可以干預每個編譯階段媚污。
  */
  plugins: [
    /*
    html-webpack-plugin 用來打包入口 html 文件
    entry 配置的入口是 js 文件舀瓢,webpack 以 js 文件為入口,遇到 import, 用配置的 loader 加載引入文件
    但作為瀏覽器打開的入口 html, 是引用入口 js 的文件耗美,它在整個編譯過程的外面京髓,
    所以,我們需要 html-webpack-plugin 來打包作為入口的 html 文件
    */
    new HtmlWebpackPlugin({
      /*
      template 參數(shù)指定入口 html 文件路徑商架,插件會把這個文件交給 webpack 去編譯堰怨,
      webpack 按照正常流程,找到 loaders 中 test 條件匹配的 loader 來編譯蛇摸,那么這里 html-loader 就是匹配的 loader
      html-loader 編譯后產(chǎn)生的字符串备图,會由 html-webpack-plugin 儲存為 html 文件到輸出目錄,默認文件名為 index.html
      可以通過 filename 參數(shù)指定輸出的文件名
      html-webpack-plugin 也可以不指定 template 參數(shù)赶袄,它會使用默認的 html 模板揽涮。
      */
      template: path.resolve(__dirname, '../index.html'),
    }),
    new VueLoaderPlugin(),
    //
    new MiniCssExtractPlugin({
      filename: devMode ? 'css/[name].css' : 'css/[name].[hash:5].css',
      chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash:5].css',
    }),
    // 解決vender后面的hash每次都改變
    /*
    使用文件路徑的 hash 作為 moduleId。
    雖然我們使用 [chunkhash] 作為 chunk 的輸出名饿肺,但仍然不夠蒋困。
    因為 chunk 內(nèi)部的每個 module 都有一個 id,webpack 默認使用遞增的數(shù)字作為 moduleId唬格。
    如果引入了一個新文件或刪掉一個文件,可能會導致其他文件的 moduleId 也發(fā)生改變颜说,
    那么受影響的 module 所在的 chunk 的 [chunkhash] 就會發(fā)生改變购岗,導致緩存失效。
    因此使用文件路徑的 hash 作為 moduleId 來避免這個問題门粪。
    */
    new webpack.HashedModuleIdsPlugin(),
    //happyPack實例
    new HappyPack({
      //用id來標識 happypack處理那里類文件
      id: 'happyBabel',
      //如何處理  用法和loader 的配置一樣
      loaders: [{
        loader: 'babel-loader?cacheDirectory=true',
      }],
      //共享進程池
      threadPool: happyThreadPool,
      //允許 HappyPack 輸出日志
      verbose: true,
      //啟用debug 用于故障排查喊积。
      debug: false
    }),
    //設置環(huán)境變量信息
    new webpack.DefinePlugin({
      //雞肋功能?
      /* 'process.env':{
        NODE_ENV: JSON.stringify(process.env.NODE_ENV)
      } */
    })

  ] // 插件
};

webpack.dev.js

// webpack.dev.js
// 存放 dev 配置
const merge = require('webpack-merge');
const common = require('./webpack.base.js');
const path = require('path');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',
  devServer: { // 開發(fā)服務器
    // dev-server 服務路徑
    contentBase: path.join(__dirname, "dist"),
    compress: true,
    host: '0.0.0.0',
    //host: 'localhost',
    port: 8085,
    // 自動打開瀏覽器
    open: true,
    // 啟動熱更新
    hot: true,
    // 顯示 webpack 構建進度
    progress: true,

    
    //重載腳本出現(xiàn)在包中,構建消息會出現(xiàn)在控制臺玄妈。
    inline: true,
    // 在頁面上全屏輸出報錯信息
    overlay: {
      warnings: true,
      errors: true
    },
    clientLogLevel: 'warning',
    // 可以進行接口代理配置
    proxy: {
      "/api": {
        target: "http://erp.my012.com:8081",
        //https會用到
        secure: false
      }
    },
    publicPath: '/'

  },
  output: { // 輸出
    filename: 'js/[name].[hash].js', // 每次保存 hash 都變化
    path: path.resolve(__dirname, '../dist')
  },
  module: {},
  plugins: [
    //命令行模式 --hot 將會自動添加此插件
    //new webpack.HotModuleReplacementPlugin()
  ]
});

webpack.prod.js

// webpack.prod.js
// 存放 prod 配置
const path = require('path');
// 合并配置文件
const merge = require('webpack-merge');
const common = require('./webpack.base.js');
// 打包之前清除文件
const CleanWebpackPlugin = require('clean-webpack-plugin');
// 分離CSS插件
//const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 壓縮CSS和JS代碼
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
//const process.env.NODE_ENV = 'production'


module.exports = merge(common, {
  module: {},
  /*
  webpack 執(zhí)行模式
  development:開發(fā)環(huán)境乾吻,它會在配置文件中插入調(diào)試相關的選項髓梅,比如 moduleId 使用文件路徑方便調(diào)試
  production:生產(chǎn)環(huán)境,webpack 會將代碼做壓縮等優(yōu)化
  */
  mode: 'production',
  devtool: 'cheap-module-source-map',
  output: {
    filename: 'js/[name].[contenthash].js', //contenthash 若文件內(nèi)容無變化绎签,則contenthash 名稱不變
    // 打包輸出目錄
    path: path.resolve(__dirname, '../dist')
  },
  plugins: [
    new CleanWebpackPlugin(['dist/*'], {
      root: path.resolve(__dirname, '../')
    })
    /* new MiniCssExtractPlugin({
      filename: "css/[name].[hash].css",
      chunkFilename: 'css/[id].[hash].css'
    }) */
  ],
  //分離不常變化的文件枯饿, 如 node_modules 下引用的庫---webpack中的字段
  optimization: {
    // 分離chunks
    splitChunks: {
      /*
      默認 entry 的 chunk 不會被拆分
      因為我們使用了 html-webpack-plugin 來動態(tài)插入 <script> 標簽,entry 被拆成多個 chunk 也能自動被插入到 html 中诡必,
      所以我們可以配置成 all, 把 entry chunk 也拆分了
      */
      chunks: 'all',
      cacheGroups: {
        common:{
          /* chunks: "initial",
          minChunks: 2,
          maxInitialRequests: 5,
          minSize: 10000 */
        },
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          chunks: "initial", // 只打包初始時依賴的第三方
          name: "vendor",
          priority: 10
          //enforce: true   //
        },
        styles: {
          /* name: 'style',
          test: /\.(sa|sc|c)ss$/,
          chunks: 'all',
          enforce: true */
        }
      }
    },
    /* runtimeChunk: {
      name: "manifest"
    }, */
    minimizer: [
      // 壓縮JS-- 自定義js優(yōu)化配置奢方,將會覆蓋默認配置
      new UglifyJsPlugin({
        exclude: /\.min\.js$/, // 過濾掉以".min.js"結尾的文件,我們認為這個后綴本身就是已經(jīng)壓縮好的代碼爸舒,沒必要進行二次壓縮
        uglifyOptions: {
          compress: {
            warnings: true, // 去除警告
            drop_debugger: true, // 去除debugger
            drop_console: true // 去除console.log
          }
        },
        cache: true, // 開啟緩存
        parallel: true, // 平行壓縮,開啟并行壓縮蟋字,充分利用cpu
        sourceMap: false,  // set to true if you want JS source maps
        extractComments: true // 移除注釋
      }),
      // 壓縮css
      new OptimizeCSSAssetsPlugin({})
    ]

  }

});

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扭勉,隨后出現(xiàn)的幾起案子鹊奖,更是在濱河造成了極大的恐慌,老刑警劉巖涂炎,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忠聚,死亡現(xiàn)場離奇詭異,居然都是意外死亡璧尸,警方通過查閱死者的電腦和手機咒林,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爷光,“玉大人垫竞,你說我怎么就攤上這事≈颍” “怎么了若未?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長钝荡。 經(jīng)常有香客問我刻撒,道長,這世上最難降的妖魔是什么重贺? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任骑祟,我火速辦了婚禮,結果婚禮上气笙,老公的妹妹穿的比我還像新娘次企。我一直安慰自己,他們只是感情好潜圃,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布缸棵。 她就那樣靜靜地躺著,像睡著了一般谭期。 火紅的嫁衣襯著肌膚如雪堵第。 梳的紋絲不亂的頭發(fā)上吧凉,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音踏志,去河邊找鬼阀捅。 笑死,一個胖子當著我的面吹牛狰贯,可吹牛的內(nèi)容都是我干的也搓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涵紊,長吁一口氣:“原來是場噩夢啊……” “哼傍妒!你這毒婦竟也來了?” 一聲冷哼從身側響起摸柄,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤颤练,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驱负,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗦玖,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年跃脊,在試婚紗的時候發(fā)現(xiàn)自己被綠了宇挫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡酪术,死狀恐怖器瘪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绘雁,我是刑警寧澤橡疼,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站庐舟,受9級特大地震影響欣除,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挪略,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一历帚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杠娱,春花似錦挽牢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽趴俘。三九已至睹簇,卻和暖如春奏赘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背太惠。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工磨淌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凿渊。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓梁只,卻偏偏與公主長得像,于是被迫代替她去往敵國和親埃脏。 傳聞我的和親對象是個殘疾皇子搪锣,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容