привет~ Уважаемые наблюдатели и господа, привет всем~ Недавно я изучал соответствующие знания о веб-пакете, когда я ясно понялwebpack
просто другойloader
иplugin
После объединения и упаковки он используется только как инструмент, который считается записью. Конечно, я столкнулся с бесчисленными ямами в процессе, и я также хотел узнать об этом больше.webpack
Принцип (в основном попадаешь в яму и вылезаешь сам). Итак, начните с простого, сначала посмотрите на использованиеwebpack
в упаковкеJS
Как загружается файл.
Дружеское напоминание, эта статья проста и понятна, даже если она не использовалась.webpack
Без проблем. Если вы уже усвоили соответствующие знания, вы можете быстро прочитать их, что расценивается как просмотр прошлого и изучение нового.На самом деле, я хочу, чтобы ты сказал мне, где я не прав..
Простая конфигурация
Так как необходимо использоватьwebpack
, надо еще настроить просто, вот простой код вставить, в первую очередьwebpack.config.js
:
const path = require('path');
const webpack = require('webpack');
//用于插入html模板
const HtmlWebpackPlugin = require('html-webpack-plugin');
//清除输出目录,免得每次手动删除
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
index: path.join(__dirname, 'index.js'),
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'js/[name].[chunkhash:4].js'
},
module: {},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
}),
//持久化moduleId,主要是为了之后研究加载代码好看一点。
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
})
]
};
Это самая простая конфигурация, которую я могу придумать.Два дополнительных загружаемых плагина используются очень часто и были кратко описаны в комментариях.
затем два простыхjs
документ:
// test.js
const str = 'test is loaded';
module.exports = str;
// index.js
const test = require('./src/js/test');
console.log(test);
Объяснять это не буду.После размещения и упаковки структура каталогов проекта должна быть такой:
На этом наша конфигурация завершена.
отindex.js
начать смотреть код
Первый из упакованныхindex.html
файл смотреть на дваJS
Порядок загрузки файлов:
<body>
<script type="text/javascript" src="js/manifest.2730.js"></script>
<script type="text/javascript" src="js/index.5f4f.js"></script>
</body>
Как видите, после упаковкиjs
Файлы загружаются в первом порядкеmanifest.js
, а потомindex.js
, надо сначала посмотретьmanifest.js
содержания. Однако давайте сначала продадим его здесь, давайте посмотримindex.js
Каково содержаниеmanifest.js
, то есть какова логика основного процесса и почему он может быть модульным.
// index.js
webpackJsonp([0], {
"JkW7": (function(module, exports, __webpack_require__) {
const test = __webpack_require__("zFrx");
console.log(test);
}),
"zFrx": (function(module, exports) {
const str = 'test is loaded';
module.exports = str;
})
}, ["JkW7"]);
После удаления всяких странных комментариев контента осталось так мало.Первое на что стоит обратить внимание этоwebpackJsonp
Эта функция, вы можете видеть, что она не находится ни под каким пространством имен, то естьmanifest.js
следует определитьwindow
Глобальная функция под,index.js
Передайте три параметра этой функции и вызовите ее.
Первый параметр — это массив, и пока непонятно, что этот массив делает.
Второй параметр — это объект, заполненный методами, которые, по-видимому, принимают как минимум два параметра (названныхzFrx
метод имеет только два параметра). Взглянув внутрь этих двух методов, я на самом деле вижу что-то очень знакомое,module.exports
, хоть и невидимыйrequire
, но по внешнему виду похож на__webpack_require__
, эти две функции должны быть ключом к модульности, сначала обратите внимание на эти две функции.
Третий параметр тоже массив, и непонятно что он делает, но заметим, что его значение равноJkW7
, что соответствует ключу метода в параметре 2, который может иметь некоторую логическую связь.
Уже,index.js
Содержаниеmanifest.js
найти ответ.
manifest.js
чтение кода
Поскольку сжатие не настроеноjs
вариант, такmanifest.js
Исходный код составляет около 150 строк, и он упрощен до 28 строк (код был запущен, и фактическое измерение не представляет проблемы). Ввиду того, что упрощенного кода на самом деле не так много, поэтому сначала я выложу код.По только что поднятым вопросам посмотрим, сколько ответов мы сможем найти:
(function(modules) {
window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
var moduleId, result;
for (moduleId in moreModules) {
if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
modules[moduleId] = moreModules[moduleId];
}
}
if (executeModules) {
for (i = 0; i < executeModules.length; i++) {
result = __webpack_require__(executeModules[i]);
}
}
return result;
};
var installedModules = {};
function __webpack_require__(moduleId) {
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
var module = installedModules[moduleId] = {
exports: {}
};
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
return module.exports;
}
})([]);
Первое, что вы должны увидеть, это то,manifest.js
внутри находитсяIIFE
, является самовыполняющейся функцией, эта функция примет в качестве параметра пустой массив, имя массиваmodules
. а потом увидел, что мыindex.js
Гипотеза вwindow
На нем есть имяwebpackJsonp
Функция. Он принимает три параметра с именемchunkIds
, moreModules
, executeModules
. соответствуетindex.js
вызыватьwebpackJsonp
Переданы три параметра. иwebpackJsonp
Какая логика внутри?
Независимо от установленных параметров,webpackJsonp
первыйfor in
пройдено один разmoreModules
,будетmoreModules
Все методы внутри существуютmodules
, который является массивом, передаваемым при выполнении самовыполняющейся функции.
После этого условное суждение:
if (executeModules) {
for (i = 0; i < executeModules.length; i++) {
result = __webpack_require__(executeModules[i]);
}
}
судитьexecuteModules
, то есть существует ли третий параметр, если он есть, то он будет выполнен__webpack_require__
метод. существуетindex.js
перечислитьwebpackJsonp
метод, этот параметр, конечно, существует, так что посмотрите на__webpack_require__
Что такое метод.
__webpack_require__
принимаетmoduleId
параметр. Внутри метода находится сначала условное суждение, независимо от того. Далее см. логику назначения
var module = installedModules[moduleId] = {
exports: {}
};
В сочетании с предыдущим условным суждением можно сделать вывод, чтоinstalledModules
является кешированным контейнером, то предыдущий код означает, что если в кеше есть соответствующий кешmoduleId
, затем напрямую вернуть егоexports
, в противном случае определите и назначьте его. Тогда взгляните__webpack_require__
Последнее возвращаемое значение , вы можете видеть, что функция возвращаетmodule.exports
,Такmodule.exports
Как он назначается? Взгляните на код после:
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
только сейчас мы знаемmodules[moduleId]
этоmoreModules
метод в , вотthis
Назначенmodule.exports
, затем поставьтеmodule
, module.exports
, __webpack_require__
Передайте его в качестве параметра для вызова. Вам знакомы эти три параметра? прежде чем мы увиделиindex.js
При написании кода внутри возникает вопрос, как достигается модульность. Здесь мы увидели глаз.
фактическиwebpack
заключается в том, чтобы положить каждыйjs
Файл инкапсулирован в функцию,require
метод соответствует__webpack_require__
,__webpack_require__
будет основываться на поступающихmoduleId
Затем загрузите соответствующий код. И когда мы хотим экспортироватьjs
значение файла, либо используйтеmodule.exports
или используйтеexports
, что соответствуетmodule
, module.exports
два параметра. Если вы не прикасаетесь к этому предмету детской обуви, вы должны понять, почему вы используете его непосредственно при экспорте значений.exports = xxx
Экспорт не удастся. Простой пример:
const module = {
exports: {}
};
function demo1(module) {
module.exports = 1;
}
demo1(module);
console.log(module.exports); // 1
function demo2(exports) {
exports = 2;
}
demo2(module.exports);
console.log(module.exports); // 1
Вставьте этот код и запустите его в браузере, и вы обнаружите, что оба отпечатка равны 1. с участиемwenpack
Логика упаковки точно такая же.
Чтобы разобраться в процессе выполнения кода после упаковки, сначалаminifest.js
определитwebpackJsonp
метод, ожидая другие упакованные файлы (также называемыеchunk
)перечислить. при звонкеchunk
, это будет сначалаchunk
все вmoreModules
, то есть каждый зависимый файл также может называтьсяmodule
(какtest.js
)спасти. проходить послеexecuteModules
Определите, является ли этот файл файлом входа, и решите, выполнять ли его в первый раз.__webpack_require__
. и__webpack_require__
, основано на этомmodule
Местоrequire
Вещи, постоянные рекурсивные вызовы__webpack_require__
,__webpack_require__
После того, как функция вернет значениеrequire
использовать. Разумеется, модули не перезагружаются, т.к.installedModules
записаноmodule
после звонкаexports
Значение , пока кеш попал, соответствующее значение будет возвращено без повторного вызоваmodule
.webpack
Упакованные файлы изолируются функциями один за другимmodule
масштаб, чтобы достичь цели не загрязнять друг друга.
резюме
Вышеупомянутоеwebpack
после упаковкиjs
Файл представляет собой простое описание процесса загрузки, на самом деле осталось еще много незаконченных деталей, например, как асинхронно загрузить соответствующий модуль,chunkId
Какую роль он играет и т. д., но из-за нехватки места(еще не исследовал), без подробностей. Соответствующий код будет размещенgithub, пожалуйста, не стесняйтесь проверить случайную точкуstar
.
Спасибо всем судьям за то, что увидели это, легче сказать, чем сделать, надеюсь, эта статья будет вам полезна~ Спасибо!