今天,我們來(lái)實(shí)現(xiàn)一個(gè)基礎(chǔ)版的webpack

前言

本質(zhì)上,webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一個(gè)依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個(gè)模塊,然后將所有這些模塊打包成一個(gè)或多個(gè) bundle。

這是官網(wǎng)對(duì)webpack的解釋。提到模塊,模塊顧名思義是獨(dú)立的JS文件。與之相近的詞模塊化,通俗的講就是我們平時(shí)組織和管理代碼方法的一種實(shí)現(xiàn)。
戰(zhàn)前準(zhǔn)備

我們先來(lái)測(cè)試一下webpack的打包。
初始化

    創(chuàng)建項(xiàng)目目錄

mkdir webpackmini

    安裝webpack依賴

yarn add webpack -D

or

npm install webpack -D

    安裝webpack-cli依賴
    這里,稍微注意一下,我們可以下載這個(gè)版本的,最新版的安裝之后好像不可用。

yarn add webpack-cli@3.3.12 -D

or

npm install webpack@3.3.12 -D

創(chuàng)建入口文件

    創(chuàng)建項(xiàng)目主目錄

mkdir src

    創(chuàng)建入口文件

touch main.js

    編輯入口文件

我們這里使用最簡(jiǎn)單的一行代碼。

console.log('maomin1');
創(chuàng)建編輯webpack 配置文件

在項(xiàng)目根目錄下鍵入命令:

touch webpack.config.js

并編輯。


const path = require('path');

module.exports = {
    mode:'development',
    entry:'./src/main.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'bundle.min.js'
    }
}

運(yùn)行測(cè)試打包

我們這里使用 npx webpack 命令進(jìn)行打包。打包成功!

我們來(lái)到打包好的bundle.min.js文件,會(huì)看到以下代碼:

/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/     var __webpack_modules__ = ({

/***/ "./src/main.js":
/*!*********************!*\
  !*** ./src/main.js ***!
  \*********************/
/***/ (() => {

eval("console.log('maomin1');\n\n//# sourceURL=webpack://webpackmini/./src/main.js?");

/***/ })

/******/     });
/************************************************************************/
/******/    
/******/     // startup
/******/     // Load entry module and return exports
/******/     // This entry module can't be inlined because the eval devtool is used.
/******/     var __webpack_exports__ = {};
/******/     __webpack_modules__["./src/main.js"]();
/******/    
/******/ })()
;

我們將注釋刪掉后,會(huì)精簡(jiǎn)不少!

(() => {
    var __webpack_modules__ = ({
        "./src/main.js":
        (() => {eval("console.log('maomin1');\n\n//# sourceURL=webpack://webpackmini/./src/main.js?");})
    });

    var __webpack_exports__ = {};
    __webpack_modules__["./src/main.js"]();
})();

準(zhǔn)備實(shí)戰(zhàn)

開(kāi)始實(shí)戰(zhàn)實(shí)現(xiàn)一個(gè)基礎(chǔ)版的webpack。

    首先我們?cè)陧?xiàng)目根目錄下創(chuàng)建一個(gè)文件夾。

mkdir maominpack

    然后,在maominpack文件夾下創(chuàng)建一個(gè)bin文件夾

mkdir bin

    最后在bin文件夾下創(chuàng)建一個(gè)maominpack.js文件

編輯如下:

#!/usr/bin/env node
const fs = require('fs');
const ejs = require('ejs');
const config = require('../../webpack.config.js');

const entry = config.entry;
const output = `${config.output.path}\/${config.output.filename}`;
const content = fs.readFileSync(entry,'utf8');

let template = `
(() => {
    var __webpack_modules__ = ({
    
    "<%-entry%>":
    (() => {
    
    eval("<%-content%>");
    
    })
    
         });
         var __webpack_exports__ = {};
         __webpack_modules__["<%-entry%>"]();
         
     })()
    ;
`

let package = ejs.render(template,{
    entry,
    content
});

fs.writeFileSync(output,package);

首先,我們?cè)陬^部指定環(huán)境為node環(huán)境,并且引入fs模塊。然后,我們引入了ejs依賴,如果不是很了解ejs的,可以去官網(wǎng)瀏覽下。這里就簡(jiǎn)單的介紹一下。

    “E” 代表什么?可以表示 “可嵌入(Embedded)”,也可以是“高效(Effective)”、“優(yōu)雅(Elegant)”或者是“簡(jiǎn)單(Easy)”。EJS 是一套簡(jiǎn)單的模板語(yǔ)言,幫你利用普通的 JavaScript 代碼生成 HTML 頁(yè)面。EJS 沒(méi)有如何組織內(nèi)容的教條;也沒(méi)有再造一套迭代和控制流語(yǔ)法;有的只是普通的 JavaScript 代碼而已。

我們看到在將帶有綁定值的字符串賦值給template變量,我們這里使用的ejs.render(),第一個(gè)參數(shù)是需要處理的字符串,第二個(gè)參數(shù)使我們需要修改的值,是一個(gè)對(duì)象。

    在package.json文件下編輯如下:

{
  "name": "maominpack",
  "version": "1.0.0",
  "bin":{
    "maominpack":"bin/maominpack.js"
  },
  "main": "index.js",
  "license": "MIT"
}

    為其命令創(chuàng)建快捷方式

npm link

    為其配置在其他目錄也可使用此命令

npm config ls

    驗(yàn)證打包

我們將src/main.js修改一下。

console.log('maomin2');

然后,鍵入命令:

maominpack

最后,檢查一下bundle.min.js:

(() => {
    var __webpack_modules__ = ({
    
    "./src/main.js":
    (() => {
    
    eval("console.log('maomin2');");
    
    })
    
         });
         var __webpack_exports__ = {};
         __webpack_modules__["./src/main.js"]();
         
     })()
    ;


發(fā)現(xiàn),我們打包成功了。這里我們只是實(shí)現(xiàn)了最基礎(chǔ)的字符串替換打包功能,webpack還有很多值得玩的特性。




作者:Vam的金豆之路

主要領(lǐng)域:前端開(kāi)發(fā)

我的微信:maomin9761

微信公眾號(hào):前端歷劫之路