Глубокое понимание того, как webpack разрешает пути кода

Node.js внешний интерфейс JavaScript Webpack

представлять

В процессе разработки с использованием основных интерфейсных фреймворков (реагирование, vue, angular) как введение модуля или пути к файлу разрешается в целевом файле? В каком порядке и порядке они были найдены? Эта проблема на первый взгляд кажется простой, особенно в небольших проектах с небольшим количеством модулей и файлов. Однако при столкновении с некоторыми более сложными проектами введение модулей и путей к файлам должно быть осторожным, что требует глубокого понимания правил анализа пути кода в веб-пакете.

дорожка

Во-первых, давайте рассмотрим три формы настройки путей в проекте.

  1. относительный путь

Относительный путь — это путь относительно текущего каталога

import {button} from '../component/button'
  1. абсолютный путь

Абсолютный путь напрямую указывает конкретное местоположение файла, и его можно найти напрямую (не рекомендуется).

import {button} from '/home/me/file'
  1. имя модуля

Если имя модуля введено напрямую, текущий каталог файлов, родительский каталог и папка node_modules (по умолчанию) в корневом каталоге будут искать, есть ли модуль с соответствующим именем.

import React from 'react'
import "module/lib/file";

Примечание. Модули node_modules по умолчанию можно настроить в соответствии с веб-пакетом.resolve.modulesвносить изменения

Примечание. Поиск будет настроен в соответствии с веб-пакетом.resolve.extensionsрасширение автозаполнения

Примечание. Поиск будет настроен в соответствии с wepackresolve.aliasзаменить псевдоним

разрешение пути

После разбора пути по вышеуказанным правилам парсер указывает путь к файлу или папке (каталогу)

  1. Если это файл, загрузите его напрямую

  2. Если это папка, узнайте, есть ли в ней файл package.json

    1) Если есть, то по умолчанию файл ищется по имени файла основного поля в нем (можно передатьresolve.mainFieldsизменения конфигурации)

    2) Если нет, ищем файл index.js по умолчанию (можно передатьresolve.mainFilesизменения конфигурации)

разрешить конфигурацию

После понимания приведенной выше формы пути и окончательных правил синтаксического анализа, согласно некоторым моим определениям, обычно можно увидеть, что конфигурация пути веб-пакета имеет место для игры.

Основной модуль для парсинга путей кода веб-пакета:enhanced-resolveмодуль

Конфигурация веб-пакета, анализирующего соответствующие пути кода, находится вresolveв

Далее мы сосредоточимся на отдельном и подробном введении в псевдоним, расширения, модули, свойства mainFields и mainFiles в разрешении.

resolve.alias

псевдоним, как следует из названия, относится к псевдониму пути. Проще говоря, это замена общего или сложного пути к файлу простым псевдонимом.

Принцип: сначала заменить, потом разобрать. При импорте модуля сначала замените ключ в соответствующем псевдониме в пути к модулю соответствующим значением, а затем выполните поиск.

Обратите внимание на несколько моментов:

  1. Заменяемый путь может быть относительным или абсолютным путем.
resolve: {
    alias: {
      '@': path.resolve(__dirname, 'components'),  
      // 这里使用 path.resolve 和 __dirname 来获取绝对路径
      // import '@/Button.js' 等同于 import '[项目绝对路径]/components/Button.js'
      x: './src/components'   // 相对路径
    }
}

2. Соответствие здесь нечеткое, а не точное. То есть псевдоним может быть сопоставлен путем переноса псевдонима в путь.

3. Обратите внимание на использование точного соответствия. с символом $ в конце ключа

resolve: {
    alias: {
        'vue$': 'vue/dist/vue.esm.js',
        'x$': 'module/dir'
        // Import 'x/file.js'  // 这里不能匹配
    }
}

resolve.extensions

Расширения файлов, которые может распознать webpack, указаны в файле extensions.

Обратите внимание на несколько моментов:

  1. Порядок сопоставления расширений. Сопоставьте слева направо. Например, в следующем примере вводится import {Button} из './component/button', и сначала будет сопоставляться button.js. Если нет button.js, будет сопоставляться button.vue и т. д. .
  2. Суффиксы, которых нет в расширениях, не будут автоматически заполнены. Например, в следующем примере нет расширения css, если вы хотите импортировать import {Button} из './style/button', оно не будет соответствовать файлу button.css.
resolve: {
    extensions: ['js', 'vue', 'json']
}

resolve.modules

Ищите модуль, который объявляет имя зависимости.По умолчанию поиск производится в каталоге node_modules. Обычно мы не изменяем эту конфигурацию.

resolve: {
  modules: ['node_modules']
},

resolve.mainFields

При ссылке на модуль укажите указанный файл, какое поле в package.json используется, по умолчанию «основной»

resolve: {
  // 配置 target === "web" 或者 target === "webworker" 时 mainFields 默认值是:
  mainFields: ['browser', 'module', 'main'],

  // target 的值为其他时,mainFields 默认值为:
  mainFields: ["module", "main"],
}

Поскольку обычно пакет модуля не объявляет поля браузера или модуля, поэтому используется main.

resolve.mainFiles

Если в каталоге нет package.json, укажите, какой файл в каталоге использовать, по умолчанию используется index.js.

resolve: {
  mainFiles: ['index'], // 可以添加其他默认使用的文件名
}

наконец

Помимо свойств, описанных выше, у разрешения есть и другие свойства, и те, кому это интересно, могут изучить его более подробно. Я надеюсь, что эта статья может стать руководством для детской обуви, которая до сих пор не знает путь к коду webpack~~