[По рукам с вебпаком] Второй шаг, интервьюер — расскажите о своем понимании модульности.

Webpack

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

2019-01-24-10-36-53
используется здесьпрограммист маленький серыйКартинка, вторглась и удалила.(пс: не знаю, оригинальная ли ссылка)

неудобные вопросы на собеседовании

В: Какие решения модульности js вы знаете?
Ответ: Модульность js обычно включает Commonjs AMD (CMD), ESModule и т. д. Синхронная загрузка, используемая Commonjs, обычно используется для узла, а AMD (CMD) обычно используется во внешнем интерфейсе из-за асинхронной загрузки. добиться модуляризации интерфейсной и серверной части. Унификация .

2019-01-24-11-10-43

В: Так почему же синхронный Commonjs используется в узле, а асинхронный AMD — во внешнем интерфейсе?
Ответ: Приложение Node запускается на сервере, и программа может напрямую читать файлы каждого модуля через файловую систему, что отличается быстрым откликом и не будет блокировать работу программы за счет синхронизации. запускается в браузере, и каждый модуль Все js-файлы должны быть загружены через HTTP-запросы.Влияет на такие факторы, как сеть, при синхронизации браузер будет выглядеть «притворной смертью»---то есть он застрянет.Это повлияет на пользовательский опыт. Вся встреча была полностью покрыта. нет ^_^.

2019-01-24-11-41-30

В: Вы слышали о webpack и знаете, как webpack реализует модульность?
Ответ: вебпакСмотри сюда, Модульность веб-пакета на самом деле заключается в перекодировании модульного кода ES6 в форму Commonjs (эй, немного паники, но вопросы интервью так запоминаются), чтобы быть совместимым с браузерами.Противоречие, это начало двигаться немного, Но сдерживаюсь, надеясь выпутаться...

88ad2618a1b1a81e05309c025

В: Хорошо, поскольку вы сказали, что синхронный способ Commonjs неприменим к внешнему интерфейсу, почему форма Commonjs, перекодированная веб-пакетом, сможет работать во внешнем интерфейсе в будущем?
Ответ: эммммм

Интервьюер: Что бы еще прийти сюда первое интервью сегодня, право, вы сначала идете обратно на такие уведомления ...
я: хмммм

2019-01-24-14-15-46

Что именно делает вебпак

Выполнял команду webpack снова и снова, и снова и снова изучал сгенерированный bundle.js. А? Все модули js упакованы в один bundle.js, а загрузки подмодулей вообще нет, так что мне все равно про синхронизацию или асинхронность.js файлы напрямую считываются в память за один шаг, что удобнее, чем nodejs, нуждающийся в чтении файлов...

Итак, как webpack объединяет так много файлов в один файл bundle.js?Подумайте об этом внимательно, или давайте учиться из книги со всеми, иначе я чувствую, что эта серия статей станет учебником по обмену пакетами emoji!2019-01-25-16-16-47

Далее я поделюсь обработкой webpack в Commonjs и es6 Module.Если есть вопросы по этим двум методам,погуглите.На самом деле так называемая модуляризация это не что иное,как добавление двух ключей к куску кода. Общайтесь с другими кодами, звоните друг другу, получайте возможность импортировать другие модули через require и реализуйте функцию экспорта методов в другие модули через export.

модульная обработка commonjs

Сначала добавьтеnpm scriptИзмените package.json, как показано ниже:

2019-01-25-16-21-54

После добавлениякод, можно отбросить./node_modules/.bin/webpackЭта команда есть сейчас, нужно только ее запаковатьnpm run buildВот и все.

2019-01-25-16-24-01

построить код проекта,кодовый адрес, где содержимое index.js:

const foo = require('./foo');

console.log(foo);
console.log('我是高级前端工程师~');

Содержимое foo.js:

module.exports = {
  name: 'quanquan',
  job: 'fe',
};

Чисто чистый код Commonjs, выполнитьnpm run buildПосле этого давайте посмотрим на упакованный bundle.js (ps: добавлены некоторые комментарии)

(function(modules) {
	// 缓存模块对象
	var installedModules = {};
	// 模拟 commonjs 实现的 require
	function __webpack_require__(moduleId) {
		// require 模块时先判断是否已经缓存, 已经缓存的模块直接返回
		if(installedModules[moduleId]) {
			return installedModules[moduleId].exports;
		}
		// (模拟)创建一个模块, 并把新模块的引用保存到缓存中
		var module = installedModules[moduleId] = {
            // 模块 id
            i: moduleId,
            // 模块是否已加载
            l: false,
            // 模块主体内容, 会被重写
			exports: {}
		};
		// 执行以下模块的包装函数, 并把模块内部的 this 志向模块主体
		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
		// 将模块标记为已加载
		module.l = true;
		// 返回模块主体内容
		return module.exports;
	}
    // 向外暴露所有的模块
	__webpack_require__.m = modules;
	// 向外暴露已缓存的模块
    __webpack_require__.c = installedModules;

    // 下边两个方法暂时还没有用到
	// define getter function for harmony exports
	__webpack_require__.d = function(exports, name, getter) {
		if(!__webpack_require__.o(exports, name)) {
			Object.defineProperty(exports, name, {
				configurable: false,
				enumerable: true,
				get: getter
			});
		}
	};
	// getDefaultExport function for compatibility with non-harmony modules
	__webpack_require__.n = function(module) {
		var getter = module && module.__esModule ?
			function getDefault() { return module['default']; } :
			function getModuleExports() { return module; };
		__webpack_require__.d(getter, 'a', getter);
		return getter;
    };

    // Object.prototype.hasOwnProperty.call 这个就没啥好解释的啦
    // js 权威指南上有说
    __webpack_require__.o = function(object, property) {
        return Object.prototype.hasOwnProperty.call(object, property);
    };

    // __webpack_public_path__
    // 这个暂时还没有用到
	__webpack_require__.p = "";
    // Load entry module and return exports
    // 准备工作做完了, require 一下入口模块, 让项目跑起来
	return __webpack_require__(__webpack_require__.s = 0);
})
/********  华丽的分割线 上边时 webpack 初始化代码, 下边是我们写的模块代码 ***************/
([
/* 模块 0 对应 index.js */
/***/ (function(module, exports, __webpack_require__) {

const foo = __webpack_require__(1);

console.log(foo);
console.log('我是高级前端工程师~');


/***/ }),
/* 模块 1 对应 foo.js */
/***/ (function(module, exports) {

module.exports = {
  name: 'quanquan',
  job: 'fe',
};


/***/ })
]);

Получается, что webpack оборачивает написанный нами код одной за другой функцией-оберткой, а затем вызывает функцию-обертку при выполнении __webpack_require__, код внутри функции-обертки переписывает атрибут exports модуля параметра в параметре, и получает нам тело код написанного модуля.

так что мы видимindex.jsОбернутый код:

function(module, exports, __webpack_require__) {
    const foo = __webpack_require__(1);
    console.log(foo);
    console.log('我是高级前端工程师~');
}

foo.jsОбернутый код:

function(module, exports) {
    module.exports = {
        name: 'quanquan',
        job: 'fe',
    };
}

Поскольку index.js имеетrequire('./foo')Поэтому __webpack_require__ используется для импорта модуля foo в параметры функции упаковки, сгенерированные index.js. От начала до конца предыдущая книга больше не кажется непонятной и сложной для понимания. Конечно, эта часть контента требует небольшой мозговой штурм .Я также надеюсь, что каждый будет оставлять свои мысли и вопросы в области комментариев, и мы будем обсуждать вместе.

2019-01-25-19-18-47

Модульная обработка модуля es6

Измените код нашего проекта на модульный код es6, сначала изменитеindex.js:

import foo from './foo';

console.log(foo);
console.log('我是高级前端工程师~');

Вторая модификацияfoo.js

export default {
  name: 'quanquan',
  job: 'fe',
};

Наконец, выполнение командной строкиnpm run buildУпакуйте его После упаковкиbundle.jsСодержание выглядит следующим образом (оптимизировано):

(function(modules) {
	var installedModules = {};
	function __webpack_require__(moduleId) {
		if(installedModules[moduleId]) {
			return installedModules[moduleId].exports;
		}
		var module = installedModules[moduleId] = {
			i: moduleId,
			l: false,
			exports: {}
		};
		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
		module.l = true;
		return module.exports;
	}
	__webpack_require__.m = modules;
	__webpack_require__.c = installedModules;
	__webpack_require__.d = function(exports, name, getter) {
		if(!__webpack_require__.o(exports, name)) {
			Object.defineProperty(exports, name, {
				configurable: false,
				enumerable: true,
				get: getter
			});
		}
	};
	__webpack_require__.n = function(module) {
		var getter = module && module.__esModule ?
			function getDefault() { return module['default']; } :
			function getModuleExports() { return module; };
		__webpack_require__.d(getter, 'a', getter);
		return getter;
	};
	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
	__webpack_require__.p = "";
	return __webpack_require__(__webpack_require__.s = 0);
})([
  function(module, __webpack_exports__, __webpack_require__) {
    "use strict";
    Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
    var __WEBPACK_IMPORTED_MODULE_0__foo__ = __webpack_require__(1);
    console.log(__WEBPACK_IMPORTED_MODULE_0__foo__["a"]);
    console.log('我是高级前端工程师~');
  },
  function(module, __webpack_exports__, __webpack_require__) {
  	"use strict";
    __webpack_exports__["a"] = ({
      name: 'quanquan',
      job: 'fe',
    });
  }
]);

Результатом упаковки по-прежнему является код небес, к счастью, он аналогичен методу модуляризации commonjs.Код инициализации веб-пакета такой же.

index.jsСгенерированный код пакета:

function(module, __webpack_exports__, __webpack_require__) {
	"use strict";
	Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
	var __WEBPACK_IMPORTED_MODULE_0__foo__ = __webpack_require__(1);
	console.log(__WEBPACK_IMPORTED_MODULE_0__foo__["a"]);
	console.log('我是高级前端工程师~');
}

foo.jsСгенерированный код пакета:

function(module, __webpack_exports__, __webpack_require__) {
	"use strict";
	__webpack_exports__["a"] = ({
		name: 'quanquan',
		job: 'fe',
	});
}

Отличие от commonjs найти несложно:

  • Во-первых, перед параметрами функции-оболочкиmodule.exportsстал__webpack_exports__
  • Во-вторых, если используется синтаксис импорта модуля es6 (import), дайте__webpack_exports__Добавлены свойства__esModule
  • Остальное похоже на commonjs

Мы обнаружили, что то, что полезно в commonjs__webpack_require__.nЭтот метод до сих пор не используется, это пустой метод?Тогда вы можете подать заявку на веб-пакет, и проекты с открытым исходным кодом, в которых вы участвовали, больше не будут пустыми.

2019-01-28-11-42-30

Не будет ли слишком легко сесть на автобус такого международного проекта с открытым исходным кодом?

2019-01-28-11-52-20

Модуль es6 CommonJs смешанное использование

Исправлятьfoo.jsСодержание следующее:

module.exports = {
  name: 'quanquan',
  job: 'fe',
};

Результат упаковки:

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__foo__ = __webpack_require__(1);
// 这里用到了 __webpack_require__.n
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__foo___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__foo__);


console.log(__WEBPACK_IMPORTED_MODULE_0__foo___default.a);
console.log('我是高级前端工程师~');
/* harmony default export */ __webpack_exports__["default"] = ({});


/***/ }),
/* 1 */
/***/ (function(module, exports) {

module.exports = {
  name: 'quanquan',
  job: 'fe',
};


/***/ })
/******/ ]);

index.jsНет никаких изменений, то есть, когда синтаксис экспорта модуля экспорта — commonjs, а синтаксис импорта импортированного модуля — es6, будет использоваться модуль импорта.__webpack_require__.nСюда.

Превью следующего эпизода: Здесь анализируется результат упаковки чистого js-файла. Webpack умно упаковывает все модули в файл bundle.js для достижения синхронной загрузки модулей, что действительно умно. Однако, если ваш проект очень большой, Сотни тысяч js-модулей, как мы можем использовать webpack для разделения кода в это время? Давайте обсудим вместе на следующем шаге.

2019-01-28-12-14-32