一張圖呈現前端模塊演化歷史

在模塊化編程中,開發者將程序分解成離散功能塊(discrete chunks of functionality),並稱之爲模塊。 精心編寫的模塊提供了可靠的抽象和封裝界限,使得應用程序中每個模塊都具有條理清楚的設計和明確的目的。

在這裏插入圖片描述

webpack 模塊定義

output: {
  library: "MyLibrary",
  libraryTarget: "umd"
}

輸出內容(不同版本的webpack略有差異,內容相符):

(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if(typeof define === 'function' && define.amd)
    define([], factory);
  else if(typeof exports === 'object')
    exports["MyLibrary"] = factory();
  else
    root["MyLibrary"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
  return _entry_return_; // 此模塊返回值,是入口 chunk 返回的值
});

也可針對不同模式指定不同名稱

output: {
  library: {
    root: "MyLibrary",
    amd: "my-library",
    commonjs: "my-common-library"
  },
  libraryTarget: "umd"
}

webpack 模塊解析

import foo from 'path/to/module'
// 或者
require('path/to/module')

webpack 使用 enhanced-resolve 來解析文件路徑(轉換爲模塊的絕對路徑)。

引子:如何處理圖片的

import logo from '@/assets/images/logo.png'
// webpack.config.js
{
  test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
  	use: [{
		loader: 'url-loader',
	    options: {
	    	limit: 4096,
	       	fallback: {
	         	loader: 'file-loader',
	         	options: { name: 'img/[name].[hash:8].[ext]' }
	       	}
		}
   }]
}

file-loader:將文件上的 import / require() 解析爲url,並輸出到輸出目錄並返回 public URL。
該圖像將被處理並添加到 output 目錄,並且 logo 變量將包含該圖像在處理後的最終 url

name: 'img/[name].[hash:8].[ext]' => /img/logo.b4d70ee2.png

PS:url-loader 功能類似於 file-loader,但是在文件大小(單位 byte)低於指定的限制時,可以返回一個 DataURL。

對於 css 或 html 中引入,處理方式類似!

background-url: url('../assets/images/logo.png') 
<img class="logo" src="../assets/images/logo.png" alt />

css-loader/html-loader 會識別這是一個本地文件,並將 '../assets/images/logo.png' 路徑,替換爲 output 目錄中圖像的最終路徑。

vue-loader: <img src="../image.png"> 將會被編譯成爲

createElement('img', {
  attrs: {
    src: require('../image.png') // 現在這是一個模塊的請求了
  }
})

默認情況下,每個本地的 <img src="image.png"> 都需要通過 require (require('./image.png'))來進行加載。

 <img class="logo" :src="require('@/assets/images/logo.png')" alt />

絕對路徑

直接使用,不需要進一步再做解析

相對路徑

import/require 中給定的相對路徑,會添加此上下文路徑(context path),以產生模塊的絕對路徑(absolute path)

模塊路徑

import "module"
import "module/lib/file"

模塊將在 resolve.modules 中指定的所有目錄內搜索。 你可以替換初始模塊路徑,此替換路徑通過使用 resolve.alias 配置選項來創建一個別名。

一旦根據上述規則解析路徑後,解析器(resolver)將檢查路徑是否指向文件或目錄。

如果路徑指向一個文件:

  • 具有文件擴展名,則直接將文件打包
  • 否則,將使用 [resolve.extensions] 選項作爲文件擴展名來解析

如果路徑指向一個文件夾:

  • 如果文件夾中包含 package.json 文件,則按照順序查找 resolve.mainFields 配置選項中指定的字段;

    • target 屬性設置爲 webworkerweb 或者沒有指定,默認值爲:

      mainFields: ["browser", "module", "main"]
      
    • 對於其他任意的 target(包括 node),默認值爲:

      mainFields: ["module", "main"]
      

    設置 target,target 同時支持 function

    module.exports = {
      target: 'node'
    }
    
    target 選項 描述
    async-node 編譯爲類 Node.js 環境可用(使用 fs 和 vm 異步加載分塊)
    electron-main 編譯爲 Electron 主進程
    electron-renderer 編譯爲 Electron 渲染進程,使用 JsonpTemplatePlugin, FunctionModulePlugin 來爲瀏覽器環境提供目標,使用 NodeTargetPlugin 和 ExternalsPlugin 爲 CommonJS 和 Electron 內置模塊提供目標
    node 編譯爲類 Node.js 環境可用(使用 Node.js require 加載 chunk)
    node-webkit 編譯爲 Webkit 可用,並且使用 jsonp 去加載分塊。支持 Node.js 內置模塊和 nw.gui 導入(實驗性質)
    web 編譯爲類瀏覽器環境裏可用(默認
    webworker 編譯成一個 WebWorker
  • 如果 package.json 文件不存在或者 package.json 文件中的 main 字段沒有返回一個有效路徑,則按照順序查找 resolve.mainFiles (解析目錄時要使用的文件名。默認:mainFiles: ["index"])配置選項中指定的文件名

  • 文件擴展名通過 resolve.extensions 選項採用類似的方法進行解析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章