3

主题

本文为webpack的基础部分, 旨在如何从0搭建一个工程环境,并简单介绍打包之后生成什么代码, 并且介绍webpack的常用的各种loader,plugin的配置 跟解决了什么问题 本篇为第一篇

项目初始化

安装webpack

yarn init -y

个人比较喜欢用yarn初始化项目 完成后

yarn add webpack webpack-cli -D

再在目录里新建一个src 文件用于放我们的源代码,src创建一个index.js作为本次的入口文件 index.js 随便输入点什么

clipboard.png
在当前目录下直接运行

npx webpack 

clipboard.png

警告我们需要配置一个mode指明是生产环境还是开发环境

打包成功 并且在目录下生成一个dist文件

npx 会去找node_modules/.bin/webpack.cmd 文件

clipboard.png

这个文件就做了一个判断 判断当前目录下有没有node.exe 有就执行当前目录下的webpack.js 没有用node执行上一级的webpack.js
webpack.js 会去找webpack-cli.js
在webpack-cli的文件目录下可以找到config-yargs.js 配置文件 其中一段代码写明了要求什么配置文件

.options({
            config: {
                type: "string",
                describe: "Path to the config file",
                group: CONFIG_GROUP,
                defaultDescription: "webpack.config.js or webpackfile.js",
                requiresArg: true
            },

这里讲明webpack默认配置文件需取名webpack.config.js 或者webpackfile.js ,
所以说,我们如果需要用自定义的名字去配置, 需要在命令行里自行添加config 指定webpack用哪个配置去打包
如:

npx webpack --config [webpack-config的path]
  

打包之后的文件

在项目根目录下新建文件webpack.config.js 并且导出去

const path = require('path')
module.exports = {
    mode:'development',  // 指定生产还是开发
    entry:'./src/index.js', // 入口文件
    output:{
        filename:'bundle.js', // 打包后的文件名
        path:path.resolve(__dirname,'./dist')  // 这里需指定一个绝对路径 我们需要node的path模块去解析路径
    }
}

再执行npx webpack

clipboard.png

看看这个bundle.js 长什么样子

clipboard.png

暂时不管__webpack_require__上的属性 简写下就是

clipboard.png

一个自执行函数传入一个obj 并且在里面自己定义了一个require方法 返回require的执行结果

obj的key是打包文件的path路径, value是一个函数 , 方法体是用eval执行index.js内部的代码。

重点就是require做了什么

clipboard.png

moduleId 就是__webpack_require__.s = './src/index.js'

定义了一个缓存 {'./src/index.js':...} 如果存在,也就是打包过了, 则直接返回,如果没有则创建一个对象

{
    i:moduleId,  // 模块的标识
    l:false, // 表示是否打包过
    exports:{}
}

并且引用给module,
然后用modules[moduleId].call 执行 modules 就是最外部传入的那个自执行函数的参数obj{'path':代码块}

这段代码就是说 执行这个obj的代码块,上下文指向module.exports, 传入module,module.exports,跟require函数做参数

(function(module, exports) {  // module对应传入的module(installedModules[moduleId]) ,exports对应module.exports
      eval("console.log('webpack')\n\n//# sourceURL=webpack:///./src/index.js?");
  })  

这段代码执行了就是输出了'webpack'

modules[moduleId].call做的事就是执行传入模块moduleId对应的代码而已

注: 如果此时index.js 内部有import 之类导入其他的模块 其他的模块也会解析成obj的key跟value格式 他会递归去用require解析

比如在index.js 里 import a from './a.js' 他的value是这样的

function(module, exports, require) {

"use strict";
eval("require.r(exports); 
    var a = require(\"./src/a.js\");   // a是require执行后返回的module.exports
    var a_default = require.n(a);  // 返回的是获取模块的函数
    console.log('webpack')");
 }

clipboard.png

require.r 就是在exports上定义了个属性作为标识

clipboard.png

require.n就是执行了require.d 并且返回了一个获取模块的方法,

clipboard.png

require.d 就是在此函数上添加了 'a', 当访问getter.a 的时候执行getter

最后:
这样层层递归 一层层打包 最终生成module.exports 返回

module.l 改变true 表示当前这个module已经打包完成 最后返回module.exports

下一节预告:webpack.config.js的配置


槐破梦
148 声望10 粉丝

学习三问: