• 从源码看webpack3打包流程


    在javascript刚刚流行时,前端项目通常比较简单,不需要考虑项目的开发效率、性能和扩展性等。

    随着前端项目越来越复杂,需要更正式的软件开发实践,比如单元测试(unit testing)、代码检查(linting)、文件缩小(minification)、文件捆绑(bundling)和代码编译(compilation)等[1]

    • 单元测试确保代码修改不影响已有功能
    • 代码检查保证一致的代码风格,没有错误
    • 文件压缩用于提高资源的访问速度,比如jpg/png、js和css等
    • 文件捆绑可以解决页面异步请求数百个js和css文件而导致的性能下降。因为每个异步请求都会有微小开销(请求头、握手等)[1],通常将这些js和css分别捆绑到一个文件中,这样将会请求一个单独的JS和CSS文件而不是数百个单独的文件
    • 代码编译是指语言预处理和转译等,比如语言预处理器SASS和JSX将CSS和JS编译成原生的,转译器Babel将ES6转译为ES5获取更好的兼容性

    将上面的开发实践看成一个个任务,这些任务与web应用的逻辑没有关联,开发这些任务也会耗费大量时间和精力。所以像grunt这样的构建工具出现了,可以通过一个命令依次运行多个任务。这些任务自动化地在开发环境运行,开发者可以专注于写应用的代码。[1]grunt的出现是跨时代的。在它之前我们经常都是通过 bash 或者 make 调用 closure-compiler 之类的工具。前端并不存在一个统一的构建工具和标准,甚至我们自己写过一些简单的构建工具。[2]

    gulp的功能类似于grunt,可以通过一个命令运行多个任务。但gulp是基于Node stream的,一个任务中的多个操作在内存中进行的;相比于grunt执行一个任务中的多个操作时,每个操作后将临时文件输出到硬盘更高效。[3]gulp优化了任务的配置,gulp的配置更简单,代码量也更少。

    当开始使用node中require()或import写浏览器代码[1],并加载npm安装的模块时,需要打包工具webpack或browserify。node样式的代码无法直接在浏览器运行。webpack或browerify会递归解析所有的require()或import的js文件,然后捆绑到一个可以通过