天天看點

前端工程建構工具 ---從零開始學習使用webpack打包Vue1.安裝2.根目錄下建立入口檔案3.正式使用webpack

1.安裝

  • 全局安裝webpack
    • 切進目前項目目錄下
    • npm install -g webpack //全局
    • npm install --save-dev webpack //安裝到目前項目下(–save-dev 是 -D 的簡寫,是項目中安裝的意思)
  • 建立package.json
    • npm init//可以自動建立這個package.json

2.根目錄下建立入口檔案

  • 項目結構

前端工程建構工具 ---從零開始學習使用webpack打包Vue1.安裝2.根目錄下建立入口檔案3.正式使用webpack
  • index.html // 引入打包完成後的js檔案,SPA應用的入口頁面
  • main.js // 入口js檔案,會引入全部的業務場景的js
  • src檔案夾 // 存放頁面内需要展示的業務代碼

3.正式使用webpack

webpack核心概念:

  • 入口(entry)
  • 輸出(output)
  • 裝飾器(loader)
  • 插件(plugins)

3.1 直接在終端啟用webpack進行打包

webpack ${入口js檔案main.js的相對路徑} -o ${打包好的js檔案bundle.js的相對路徑}
webpack main.js -o dist/bundle.js
           

3.2 利用webpack.config.js配置檔案進行打包(常用)

3.2.1建立webpack.config.js檔案

module.exports = {
    entry: __dirname + "入口檔案main.js相對路徑",//入口
    output:{
        path: __dirname + "/dist", // 打包後輸出檔案的路徑,該檔案夾在目前目錄下是不存在的
        fileName: "bundle.js" // 打包後輸出的js檔案,該檔案在目前目錄下是不存在的
    }
}
           

注意:__dirname是node.js中的一個全局變量,它指向目前執行腳本所在的目錄

3.2.2 在package.json中定義啟動webpack的打包指令

{
    "name": "webpack-demo",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": { //在這定義啟動webpack的指令
        "start": "webpack",//隻有start指令可以用 npm start
        "test": "echo \"Error: no test specified\" && exit 1",//其他都要用 npm run test
        "dev": "webpack-dev-server --port 9999" //其他都要用 npm run dev
    },
    "author": "ly",
    "license": "ISC",
    "devDependencies": {
        "webpack": "^4.41.6",
        "webpack-cli": "^3.3.11",
        "webpack-dev-server": "^3.10.3"
    }
}
           

注意:package.json中的script會按一定順序尋找指令對應位置,本地的node_modules/.bin路徑就在這個尋找清單中,是以無論是全局還是局部安裝的Webpack,你都不需要寫前面那指明詳細的路徑了

3.2.3 source-map

  • 正常webpack的工作流程為:代碼打包壓縮 -> 去空格 ->babel(後面會介紹babel的用途)編譯轉換
  • 打包壓縮編譯後的項目代碼和源代碼之間有很大的差異,為了友善調試,定位編譯後的代碼的具體報錯資訊,我們通常用Source Maps來定位到開發中的源代碼。
  • devtool:

    devtool是為了在webpack中配置Source Maps,友善在控制台中找到報錯資訊具體出現在代碼的第幾行中

    module.exports = {
          devtool: 'eval-source-map', // source-map有很多種,自行百度各種差別
          //__dirname 指的是目前檔案所在路徑
          //entry後指定入口檔案
          entry: __dirname + "/main.js",
          output: {
              //打包後輸出檔案位址
              path: __dirname + "/dist",
              filename: "bundle.js"
          }
      } 
               

3.2.4 使用webpack建構本地伺服器

  • webpack提供一個可選的本地開發伺服器 webpack-dev-server
  • 在webpack中進行配置之前需要單獨安裝它作為項目依賴

    npm install --save-dev webpack-dev-server

    module.exports = {
          devtool: 'eval-source-map',
          //__dirname 指的是目前檔案所在路徑
          //entry後指定入口檔案
          entry: __dirname + "/main.js",
          output: {
              //打包後輸出檔案位址
              path: __dirname + "/dist",
              filename: "bundle.js"
          },
          devServer: {
              // devServer 還有很多配置項,自行百度
              contentBase: __dirname, //預設webpack-dev-server會為根檔案夾提供本地伺服器,如果想為另外一個目錄下的檔案提供本地伺服器,應該在這裡設定其所在目錄(本例設定到根目錄)
              historyApiFallback: true, //在開發單頁應用時非常有用,它依賴于HTML5 history API,如果設定為true,所有的跳轉将指向index.html
              inline: true //設定為true,當源檔案改變時會自動重新整理頁面
          }
      }
               
  • webpack.config.js中配置好後可在package.json 的script中去定義啟動的指令,我這裡設定了端口為9999
    前端工程建構工具 ---從零開始學習使用webpack打包Vue1.安裝2.根目錄下建立入口檔案3.正式使用webpack

3.2.5 Loaders(很重要,面試常問掌握哪些loaders)

package.json結構如下

{
    "name": "webpack-demo",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "cross-env NODE_ENV=production webpack --config webpack.config.js",
        "dev": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --progress --color --port 9999 --config webpack.config.js"
    },
    "author": "ly",
    "license": "ISC",
    "devDependencies": {
        "babel-core": "^6.26.3", //babel核心包
        "babel-loader": "^7.1.5",//處理ES6文法
        "babel-preset-env": "^1.7.0", //根據你支援的環境自動決定适合你的Babel插件
        "babel-preset-es2015": "^6.24.1", //安裝了上個這個其實可以不安裝,再上一個裡直接配置
        "cross-env": "^7.0.2", //跨平台包,可以擷取目前環境
        "css-loader": "^3.5.2",//解析css代碼,按子產品打包進bundle.js中
        "html-webpack-plugin": "^4.2.0",//見後文
        "node-sass": "^4.13.1",// sass-loader依賴于node-sass
        "sass-loader": "^8.0.2",//解析sass檔案,<style > 這樣才能正常渲染
        "style-loader": "^1.1.4",//配合css-loader将解析的代碼以style标簽插入代碼中
        "vue": "^2.6.11", // 沒啥說的(⊙o⊙)
        "vue-loader": "^15.9.1",//解析和轉換 .vue 檔案
        "vue-template-compiler": "^2.6.11",//vue-loader依賴vue-template-compiler
        "webpack": "^4.41.6",// 沒啥說的(⊙o⊙)
        "webpack-cli": "^3.3.11",// 沒啥說的(⊙o⊙)
        "webpack-dev-server": "^3.10.3"// 本地打包調試,不會生成真正的打封包件,因為支援熱部署,是以把檔案都放進記憶體中快速更新
    }
}
           
  • 1.Loader 用來幫助webpack解析除js類型外的其他檔案
  • 2.Loader 可以了解為是子產品和資源的轉換器,它本身是一個函數,接受源檔案作為參數,傳回轉換的結果。這樣,我們就可以通過 require 來加載任何類型的子產品或檔案,比如 CoffeeScript、 JSX、 LESS 或圖檔。
  • 3.Loaders需要單獨安裝并且需要在webpack.config.js中的modules關鍵字下進行配置
    • test:一個用以比對loaders所處理檔案的拓展名的正規表達式(必須)
    • loader:loader的名稱(必須)
    • include/exclude:手動添加必須處理的檔案(檔案夾)或屏蔽不需要處理的檔案(檔案夾)(可選);
    • query:為loaders提供額外的設定選項(可選)
  • 4.介紹幾個常用loader
    • Babel
      • Babel的作用:
        • 主要用來編譯js/jsx代碼,支援ES6,ES7最新文法格式,不需要考慮浏覽器是否支援
        • Babel預設隻轉換新的javascript文法,而不轉換新的API,比如 Iterator, Generator, Set, Maps, Proxy, Reflect,Symbol,Promise 等全局對象。以及一些在全局對象上的方法(比如 Object.assign)都不會轉碼
      • Babel的安裝與配置:e
        • Babel其實是幾個子產品化的包,其核心功能位于稱為babel-core的npm包中
        • 可以直接在webpack -> loaders 裡進行配置
        • 也可以在項目的根目錄下建立一個.babelrc檔案(babel轉碼檔案),專門配置babel的各種屬性,不需要特别引用,webpack通過babel進行編譯時會自動從根目錄下進行搜尋
          前端工程建構工具 ---從零開始學習使用webpack打包Vue1.安裝2.根目錄下建立入口檔案3.正式使用webpack
      • 參考連結:
        • https://www.cnblogs.com/tugenhua0707/p/9452471.html
    • babel-polyfill
      • 原理:
        • 向全局對象和内置對象的prototype上添加方法來實作的。比如運作環境中不支援Array.prototype.find 方法,引入polyfill, 我們就可以使用es6方法來編寫了,但是缺點就是會造成全局空間污染

3.2.6 plugins

webapck.config.js結構如下

const rimraf = require('rimraf');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');
var htmlWebpackPlugin = require('html-webpack-plugin');//下面有介紹

// 删除 dist 目錄
rimraf.sync('dist');

module.exports = {
    mode: process.env.NODE_ENV,
    devtool: 'eval-source-map',
    //__dirname 指的是目前檔案所在路徑
    //entry後指定入口檔案
    entry: __dirname + "/main.js",
    output: {
        //打包後輸出檔案位址
        path: __dirname + "/dist",
        filename: "bundle.js"
    },
    devServer: {
        // contentBase: __dirname,
        historyApiFallback: true,
        inline: true,
        hot: true
    },
    module: {
        rules: [{
            test: /\.(sa|sc|c)ss$/,
            use: ['style-loader', 'css-loader', 'sass-loader']
        }, {
            test: /\.js$/,
            loader: 'babel-loader',
            options: {
                presets: ['env']
            },
            // 不去編譯依賴中的js檔案,優化加快速度
            exclude: /node_modules/
        }, {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: {
                loaders: {
                    scss: ['sass-loaders'],
                }
            }
        }, ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new htmlWebpackPlugin({
            template: __dirname + '/index.html', //模闆路徑
            filename: 'index.html' //自動生成的HTML檔案的名稱
        })
    ]
}
           
  • plugin 用來擴充webpack的功能
  • 介紹幾個常用plugin:
    • html-webpack-plugin
      • html-webpack-plugin作用:
        • 1.為html檔案中引入的外部資源如script、link動态添加每次compile後的hash,防止引用緩存的外部檔案問題
        • 2.可以在打包後的檔案中建立html入口檔案,不配置的話打包出來隻會有output處配置的js,比如單頁面可以生成一個html檔案入口,配置N個html-webpack-plugin可以生成N個頁面入口
        • 3.這個loader如果不引用,webpack-dev-server在本地調試時,vue檔案不渲染,隻會渲染inde.html檔案内的内容,但直接使用webpack打出的檔案是可以正常渲染的,具體原因還不清楚😂
    • mini-css-extract-plugin
      • mini-css-extract-plugin作用:
        • 1.從bundle.js中提取css
        • 2.增加hash性能優化
          • 啥是hash?關于hash性能優化參考這篇博文
            • 版本疊代更新的過程中,修改某個檔案,更新時不要覆寫那個檔案,而是産生一個新檔案
              前端工程建構工具 ---從零開始學習使用webpack打包Vue1.安裝2.根目錄下建立入口檔案3.正式使用webpack
            • ”_82244e91”這串字元是根據a.js的檔案内容進行hash運算得到的,隻有檔案内容發生變化了才會有更改