webpack4.0 基礎準備

webpack官方文檔地址鏈接 ,本文主要介紹開始webpack前的準備工作。

  • 前言

為什么要引入webpack

??隨著前端工程越來越復雜,單獨創(chuàng)建html js css的方式已經無法保證項目的可維護性,所以我們就需要考慮把不同的業(yè)務邏輯拆分成模塊,然后分開引入這些模塊,每個模塊做自己的事情,這樣就可以保證項目的可維護性和可擴展性了。假如我們一個復雜的工程需要幾千個js文件,我們不可能引入幾千個js文件,所以我們需要借助工具來管理模塊,目前使用率最高的有webpackGRUNT、Gulp、Browserify,并且Vue,React,Angular腳手架都開始使用webpack做底層框架,主要得益于它的Tree Shaking 代碼懶加載 代碼分割 等特性。

什么是webpack

??官方介紹:webpack是一個現(xiàn)代 JavaScript應用程序的靜態(tài)模塊打包器(module bundler)。當 webpack處理應用程序時,它會遞歸地構建一個依賴關系圖(dependency graph),其中包含應用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 bundle。核心定義為:‘模塊打包工具’。那么,在了解webpack之前,首先要清楚什么是模塊,如何使用模塊。

什么是modules

??在模塊化編程中,開發(fā)者將程序分解成離散功能塊(discrete chunks of functionality),并稱之為模塊。
??每個模塊具有比完整程序更小的接觸面,使得校驗、調試、測試輕而易舉。 精心編寫的模塊提供了可靠的抽象和封裝界限,使得應用程序中每個模塊都具有條理清楚的設計和明確的目的。
??以上是官方的介紹,以我自己的理解,程序我可以理解為車輪,我們都知道,車輪有輪胎和輪轂,那么輪胎的生產線生產輪胎這個零件,輪轂的生產線生產輪轂這個零件,各自分工互不打擾,那么輪胎和輪轂的生產線我們可以理解為模塊,而產出的輪胎和輪轂我們可以理解為模塊的方法,而生產出輪胎和輪轂的過程我們可以理解為導出,而車間人員拿過來組裝的過程我們可以理解為導入。


常見的webpack modules

?? ES Module 、CommonJS 、 CMD、AMD、 css/sass/less 文件中的 @import 語句...

相關modules使用方法

  • Es Module

export 默認導出整個模塊,或具名導出模塊

// 具名導出
export let Hello = 'Echonessy';
export const Word = () => {  return ‘Boy’; }

// 默認導出
export default {
  Hello,Word
}

import通過 import 以靜態(tài)的方式,導入另一個通過 export 導出的模塊。

//  具名導出的引用
import { Hello,Word } from './hello-word.js';
// 使用方式
Hello;
Word();

//  默認導出的引用 HelloWord 包含Hello、Word兩個對象
import HelloWord from './hello-word.js';
// 使用方式
HelloWord.Hello;
HelloWord.Word();
  • export導出多個對象,export default只能導出一個對象并且一個文件里只能有一個。
  • export導出對象需要用{ },export default不需要{ }
export {A,B,C};
export default A;

import()動態(tài)地加載模塊。調用 import()之處,被作為分離的模塊起點,意思是,被請求的模塊和它引用的所有子模塊,會分離到一個單獨的 chunk 中。

import規(guī)范不允許控制模塊的名稱或其他屬性,因為 "chunks" 只是 webpack中的一個概念。幸運的是,webpack中可以通過注釋接收一些特殊的參數(shù),而無須破壞規(guī)定,具體參數(shù)介紹請參考官方文檔

import(
   /* webpackChunkName: "newChunkName" */
   /* webpackMode: "lazy" */
    './hello-word.js'
).then(HelloWord =>{
      HelloWord.Hello;
      HelloWord.Word();
    }).catch(e => { })
  • CommonJS

require以同步的方式檢索其他模塊的導出。由編譯器(compiler)來確保依賴項在最終輸出 bundle 中可用。對應的導出方法為exportsmodule.exports

const HelloWord = require('HelloWord');

exports 、module.exports:一個模塊被引用的時候最終都會被輸出成module.exports,而exports只是module.exports的一個引用

const helloWord = require('../controllers/helloWord');
module.exports = helloWord;
console.log(module)
// 控制臺打印如下
Module {
  id: 'E:\\ExpServer\\routes\\index.js',
  exports: { Hello: [Function] }
  ...
  }

require.resolve以同步的方式獲取模塊的 ID。由編譯器(compiler)來確保依賴項在最終輸出 bundle 中可用。更多關于模塊的信息,請點擊這里 module.id。使用require.resolve函數(shù)查詢模塊文件名時并不會加載該模塊。

module.id === require.resolve("./HelloWord.js")

require.cache多處引用同一個模塊,最終只會產生一次模塊執(zhí)行和一次導出。所以,會在運行時(runtime)中會保存一份緩存。刪除此緩存,會產生新的模塊執(zhí)行和新的導出。

require.cache[module.id] === module

require.ensure()是 webpack 特有的,已經被 import() 取代。

  • webpack 特定的方法

require.context()使用 directory 路徑、includeSubdirs 選項和 filter 來指定一系列完整的依賴關系,便于更細粒度的控制模塊引入。
當我們需要引入某一目錄下多個文件的時候,一個一個的導入似乎會顯得非常麻煩,這里我們就可以考慮使用此方法獲取該目錄下的文件,通過提取注入到一個文件里。

require.context(directory:String, includeSubdirs:Boolean /* 可選的,默認值是 true */, filter:RegExp /* 可選的 */);

require.include引入一個不需要執(zhí)行的依賴,這可以用于優(yōu)化輸出 chunk中的依賴模塊的位置。

require.include(dependency: String)

webpack 環(huán)境搭建

準備工作:nodeJs ,這里我們最好安裝最新版本的,因為會提升webpack打包速度,
下載下來之后,傻瓜式安裝完成之后打開CMD輸入以下指令

G:\Echonessy>node -v
v10.16.3

G:\Echonessy>npm -v
6.9.0

這樣說明nodenpm安裝完畢

接下來我們新建一個文件夾,作為我們webpack的工程目錄webpackDemo,我們通過npm進行初始化,讓它符合webpack的使用環(huán)境具體指令

G:\Echonessy\webpack>cd webpackDemo

G:\Echonessy\webpack\webpackDemo>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (webpackdemo)
version: (1.0.0)
description: this is a demo
entry point: (index.js)
test command:
git repository:
keywords:
author: Echonessy
license: (ISC)
About to write to G:\Echonessy\webpack\webpackDemo\package.json:

{
  "name": "webpackdemo",
  "version": "1.0.0",
  "description": "this is a demo",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Echonessy",
  "license": "ISC"
}


Is this OK? (yes) yes

接下來我們就會發(fā)現(xiàn)文件夾里多了一個package.json文件


初始化完成之后,那么接下來開始安裝webpack(注,webpack可能會出現(xiàn)安裝失敗的情況,這里是由于webpack源會被國內強掉,這里可以通過手機熱點來連接WIFI安裝),我們首先進入webpackDemo這個目錄下


//  項目內安裝webpack(建議)
npm install webpack webpack-cli -D 

G:\Echonessy\webpack\webpackDemo>npm install webpack webpack-cli -D
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN webpackdemo@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: 
wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ webpack-cli@3.3.7
+ webpack@4.39.2
added 385 packages from 218 contributors and audited 5286 packages in 441.279s
found 0 vulnerabilities

// 查看版本  npx 想要解決的主要問題,就是調用項目內部安裝的模塊
G:\Echonessy\webpack\webpackDemo>npx webpack -v
4.39.2



//  全局安裝webpack(不建議,因為如果存在多個項目假如各項目webpack版本不同,會有問題)
npm install webpack webpack-cli -g

webpack 配置

webpack的打包文件為webpack.config.jswebpack默認內部有打包配置,如果找不到配置文件會執(zhí)行內部默認配置。

G:\Echonessy\webpack\webpackDemo>npx webpack index.js
Hash: 53742f9efd12248f7206
Version: webpack 4.39.2
Time: 941ms
Built at: 2019-08-21 2:40:55 PM
  Asset      Size  Chunks             Chunk Names
main.js  5.09 KiB       0  [emitted]  main
Entrypoint main = main.js
[0] ./index.js 365 bytes {0} [built]
    + 2 hidden modules

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 
'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

默認會把index.js文件打包成main.js并且存放在dist文件夾下
那么如何配置我們自定義的規(guī)則?

這里我們新建一個index.js作為需要打包的文件
新建一個webpack.config.js配置文件

image.png

那么接下來我們需要在配置文件里去配置我們需要打包的規(guī)則
打開webpack.config.js配置文件

const path = require('path');

module.exports = {
    //兩種模式  development 代碼不會被壓縮  production會被壓縮
    mode: 'development',   
    //入口
    entry: './index.js', // 我們需要打包的文件
    //出口
    output:{
        filename:'outBundle.js',// index.js打包后的文件名字
        path: path.resolve(__dirname,'bundle'),//index.js打包后所在的文件夾
    }
}

執(zhí)行打包配置

G:\Echonessy\webpack\webpackDemo>npx webpack
Hash: b82930305775bdc66443
Version: webpack 4.39.2
Time: 650ms
Built at: 2019-08-21 2:50:15 PM
       Asset       Size  Chunks             Chunk Names
outBundle.js  930 bytes       0  [emitted]  main
Entrypoint main = outBundle.js
[0] ./index.js 49 bytes {0} [built]


這里我們會發(fā)現(xiàn),我們的工程多出了一個文件夾bundle文件夾,里面有個outBundle.js

image.png

那么問題來了,這個配置文件我想自己命名,并且放到配置文件目錄里,這個時候打包的時候該怎么辦?

這里我把webpack.config.js重命名為webpackConfig.js并且放在config文件夾下面

image.png

這里,我們就需要通過命令指定配置文件去打包,我們進入到config目錄下通過--config 指向webpackConfig.js,這樣就可以打包成功了。

const path = require('path');

module.exports = {
    mode: 'development',
    //入口
    entry: '../index.js', // 我們需要打包的文件
    //出口
    output:{
        filename:'newOutBundle.js',// index.js打包后的文件名字
        path: path.resolve(__dirname,'../newBundle'),//index.js打包后所在的文件夾
    }
}


G:\Echonessy\webpack\webpackDemo\config>npx webpack --config webpackConfig.js
Hash: b82930305775bdc66443
Version: webpack 4.39.2
Time: 186ms
Built at: 2019-08-21 3:02:21 PM
          Asset       Size  Chunks             Chunk Names
newOutBundle.js  930 bytes       0  [emitted]  main
Entrypoint main = newOutBundle.js
[0] ../index.js 49 bytes {0} [built]

G:\Echonessy\webpack\webpackDemo\config>

以上打包每次都需要用npx webpack 這種固定語法去打包我們的文件,那么問題來了,這指令我們可不可以自定義?我們都知道,vue有兩種我們常用的指令,一個是npm run dev一個是npm run build,那么我們是否可以創(chuàng)建我們自己的指令?答案是肯定的

首先,我們打開package.json 會有個scripts對象 這里我們新建一個指令,取名為setup,執(zhí)行的語句為webpack

{
  "name": "webpackdemo",
  "version": "1.0.0",
  "description": "this is a demo",
  "main": "index.js",
  "scripts": {
    "setup": "webpack"
  },
  "author": "Echonessy",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.39.2",
    "webpack-cli": "^3.3.7"
  }
}

執(zhí)行后你會發(fā)現(xiàn)
npx webpack == npm run setup


實例1:

我們都知道,瀏覽器是不能直接運行es6的相關語法的,那么,如果我們要運行,該怎么處理?其實webpack還可以進行代碼的簡單 '翻譯'。

這里我們實現(xiàn)一個簡單的需求,就是我們有兩個模塊,分別對應AB,將AB通過模塊的內容通過導入導出方式顯示在頁面上。

這里我們新建個文件夾src用來存放我們的源代碼

image.png

我們新建一個a.js

export const A = () => {
    return "I'm A";
}

我們新建一個b.js

export const B = () => {
    return "I'm B";
}

新建一個index.js作為模塊引入文件

import { A } from './a.js'
import { B } from './b.js'
document.getElementById('main').innerHTML = A() + '</br>' + B();

同樣的,我們需要創(chuàng)建一個index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="main"></div>
<script src="./index.js"></script>
</body>
</html>

我們直接運行,可以看到,瀏覽器控制臺會報index.js的語法錯誤,并且,我們的頁面也沒有顯示任何東西。

image.png

那么這里我們創(chuàng)建一個webpack配置文件 將我們的index.js打包出來

const path = require('path');
module.exports = {
    mode: 'production',
    //入口
    entry: './src/index.js', // 我們需要打包的文件
    //出口
    output:{
        filename:'newIndex.js',// index.js打包后的文件名字
        path: path.resolve(__dirname,'newDist'),//index.js打包后所在的文件夾
    }
}

我們執(zhí)行在工程目錄下執(zhí)行

npx webpack src/index.js

或者執(zhí)行我們自定義的指令

G:\Echonessy\webpack\webpackDemo>npm run setup

> webpackdemo@1.0.0 setup G:\Echonessy\webpack\webpackDemo
> webpack

Hash: e4f933d03797360cf137
Version: webpack 4.39.2
Time: 162ms
Built at: 2019-08-21 4:19:06 PM
      Asset        Size  Chunks             Chunk Names
newIndex.js  1010 bytes       0  [emitted]  main
Entrypoint main = newIndex.js
[0] ./src/index.js + 2 modules 373 bytes {0} [built]
    | ./src/index.js 173 bytes [built]
    | ./src/a.js 100 bytes [built]
    | ./src/b.js 100 bytes [built]

這樣我們新的index.js打包文件就打包完成了,接下來,我們更改index.htmljs引入路徑

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="main"></div>
<script src="../newDist/newIndex.js"></script>
</body>
</html>

我們再次打開瀏覽器,發(fā)現(xiàn)我們想要的效果出來了


image.png
以上是相關簡單的webpack介紹和基礎使用方法,后續(xù)會持續(xù)更新其他相關的用法......
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容