现代前端开发离不开打包工具,以 webpack 为代表的打包工具已经成为日常开发必备之利器,拿 React 技术栈为例,我们 ES6 形式的源代码,需要经过 webpack 和 Babel 处理,才能生成发布版文件,在浏览器中运行。今天就结合 React 来梳理一下 webpack 打包时模块的组织结构,先给定下面一个简单的应用示例:

import React from 'react';
import ReactDOM from 'react-dom'; import {greet} from './utils'; const App = <h1>{greet('scott')}</h1>; ReactDOM.render(App, document.getElementById('root'));

代码中的 utils 模块如下:

export function greet(name) {
return `hello ${name}`;
}

如果编译该示例代码,由于要将第三方库一起打包,最终生成的目标代码会比较多,所以我们先在 webpack.config.prod.js 中将 React 和 ReactDOM 配置为 externals,不将它们编译到目标代码中,而是在运行时直接从外部取值。配置如下:

let appConfig = {
entry: './src/index.js',
externals: {
'react': 'React',
'react-dom': 'ReactDOM',
},
output: {
path: './dist',
filename: 'index.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
};

运行 webpack,生成的目标代码如下:

(function (modules) {
// 存放已加载的模块
var installedModules = {}; // 加载函数
function __webpack_require__(moduleId) {
// 如果该模块已被加载 直接返回module.exports
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
} var module = installedModules[moduleId] = {
exports: {},
id: moduleId,
loaded: false
}; // 调用模块函数 加载相应的模块
// 参数是(module, exports[, __webpack_require__])
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // 标记该模块已被加载
module.loaded = true; // 最后也返回exports
return module.exports;
} // 暴露modules和installedModules对象
__webpack_require__.m = modules;
__webpack_require__.c = installedModules; // __webpack_public_path__
__webpack_require__.p = ""; // 加载主模块
return __webpack_require__(0);
})
/* 以下是模块列表 作为参数被加载 */
([
/* 0 主模块 */
(function (module, exports, __webpack_require__) {
'use strict'; // 取索引为1的React模块
var _react = __webpack_require__(1); var _react2 = _interopRequireDefault(_react); // 取索引为2的ReactDOM模块
var _reactDom = __webpack_require__(2); var _reactDom2 = _interopRequireDefault(_reactDom); // 取索引为3的utils模块
var _utils = __webpack_require__(3); // 模块取值 不包含__esModule:true的是默认导出
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
} // 开始渲染视图 var App = _react2.default.createElement(
'h1',
null,
(0, _utils.greet)('scott')
); _reactDom2.default.render(App, document.getElementById('root'));
}),
/* 1 React模块 */
(function (module, exports) {
module.exports = React;
}),
/* 2 ReactDOM模块 */
(function (module, exports) {
module.exports = ReactDOM;
}),
/* 3 utils模块 */
(function (module, exports) {
"use strict"; Object.defineProperty(exports, "__esModule", {
value: true
}); exports.greet = greet; function greet(name) {
return "hello " + name;
}
})
]);

上面就是基本的模块加载机制。其实,有了 externals 配置,我们也可以不在代码中引入 React 和 React-DOM,下面稍微修改一下代码:

import {greet} from './utils';

const App = <h1>{greet('scott')}</h1>;

ReactDOM.render(App, document.getElementById('root'));

转译后的代码如下:

(function (modules) {
// ...
})
/* 以下是模块列表 作为参数被加载 */
([
/* 0 主模块 */
(function (module, exports, __webpack_require__) {
'use strict'; // 取索引为1的utils模块
var _utils = __webpack_require__(1); // 开始渲染视图 var App = React.createElement(
'h1',
null,
(0, _utils.greet)('scott')
); ReactDOM.render(App, document.getElementById('root'));
}),
/* 1 utils模块 */
(function (module, exports) {
"use strict"; Object.defineProperty(exports, "__esModule", {
value: true
}); exports.greet = greet; function greet(name) {
return "hello " + name;
}
})
]);

可以看到,代码清晰了不少,主模块中直接调用 React.createElement() 来创建虚拟 DOM 对象,最后调用 ReactDOM.render() 方法来渲染真实的 DOM 结点。访问下面的入口文件,我们就可以看到程序运行的结果:

<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="index.js"></script>
</body>
</html>

React: webpack模块组织关系的更多相关文章

  1. React系列文章:Webpack模块组织关系

    现代前端开发离不开打包工具,以Webpack为代表的打包工具已经成为日常开发必备之利器,拿React技术栈为例,我们ES6形式的源代码,需要经过Webpack和Babel处理,才能生成发布版文件,在浏 ...

  2. 部署React+webpack工程的步骤

    # 部署React+webpack工程的步骤ps:以Mac os系统做开发环境.因为npm现在使用灰常的慢,所以我使用淘宝境像cnpm. 1,准备工作: 先确保存已经安装了node.js: 2,文件部 ...

  3. react webpack.config.js 入门学习

    在学习react 的时候必然会用到webpack打包工具,webpack的快速入门另外一篇文章中有记录,这里只记录webpack.config.js文件,因为每个项目下都必须配置,通俗的讲,它的作用就 ...

  4. 真刀实战地搭建React+Webpack+Express搭建一个简易聊天室

    一.前面bb两句 因为自惭(自残)webpack配置还不够熟悉,想折腾着做一个小实例熟悉.想着七夕快到了,做一个聊天室自己和自己聊天吧哈哈.好了,可以停止bb了,说一下干货. 二. 这个项目能学到啥? ...

  5. react常用模块介绍

    react各个模块: 1.node.js自带的模块(原生模块):https://www.jianshu.com/p/abc72267abfc原生模块的api文档地址:http://nodejs.cn/ ...

  6. React + webpack 环境配置

    安装配置Babel babel-preset-es2015 ES6语法包,使代码可以随意地使用ES6的新特性. babel-preset-react React语法包,专门用于React的优化,在代码 ...

  7. 每天记录一点:NetCore获得配置文件 appsettings.json vue-router页面传值及接收值 详解webpack + vue + node 打造单页面(入门篇) 30分钟手把手教你学webpack实战 vue.js+webpack模块管理及组件开发

    每天记录一点:NetCore获得配置文件 appsettings.json   用NetCore做项目如果用EF  ORM在网上有很多的配置连接字符串,读取以及使用方法 由于很多朋友用的其他ORM如S ...

  8. 用React & Webpack构建前端新闻网页

    这是一篇给初学者的教程, 在这篇教程中我们将通过构建一个 Hacker News 的前端页面来学习 React 与 Webpack. 它不会覆盖所有的技术细节, 因此它不会使一个初学者变成大师, 但希 ...

  9. scss + react + webpack + es6

    scss + react + webpack + es6 写在前面: 刚学习完慕课网里的一个幻灯片案例,自己加了刚学的react,两者结合.首先让大家看看效果 点击此处 你可以先用纯js实现上面的效果 ...

随机推荐

  1. 《绯雨骑士团》Demo,框架实现,寻路打怪

    在家无事花几天做了个放置挂机demo,做着玩吧.和海拓的<凡人修仙传>类似吧,自动挂机刷怪打boss数值游戏,但是我比较喜欢二次元的,所以选了<绯雨骑士团>的资源. 参考了以下 ...

  2. vbscript--FileSystemObject详解

    https://blog.csdn.net/superbirds/article/details/6762748 FSO是FileSystemObject 或 Scripting.FileSystem ...

  3. CVI中调用VC动态库

    1.在VC环境中建立新工程,创建32位动态库(Win32 Dynamic-Link Library)  -> A simple DLL project 2.在工程中可加入别的动态库,在工程菜单中 ...

  4. Java之数组类型

    如果我们有一组类型相同的变量.例如,5位同学的成绩,可以这么写 public class Main { public static void main(String[] args) { // 5位同学 ...

  5. adb 命令简介

    adb命令配置 1 在命令行下,进入用户目录 cd $HOME 2 .bash_profile文件 输入下行命令获取当前文件列表: ls -al 查看文件列表,如果没有.bash_profile文件, ...

  6. 【视频开发】Gstreamer中一些gst-launch常用命令

    GStreamer是著名的开源多媒体框架,功能强大,其命令行程序 gst-launch 可以实现很多常规测试.播放等,作为系统调试等是非常方便的. 1.摄像头测试 gst-launch v4l2src ...

  7. java 查看类是从哪个jar包加载的

    package com.jason object FIndjar { def main(args: Array[String]): Unit = { val pd = classOf[org.apac ...

  8. electron+vue实现菜单栏

    公司开发的产品都是用c++写的,而且还都是几个人,老板想搞下创新,就是看看能否通过其它的方式来实现前后端分离.然后我就了解到了electron这个东西,之前学安卓的时候看到过flutter,不经意间看 ...

  9. Beautiful Soup库入门

    1.安装:pip install beautifulsoup4 Beautiful Soup库是解析.遍历.维护“标签树”的功能库 2.引用:(1)from bs4 import BeautifulS ...

  10. git最基本的操作: add commit push 哈哈

    Git add     //添加到本地暂存区 Git commit -m”xxxxx”   //添加到本地分支 Git push      //添加到远端分支