1、什么是webpack

Webpack​ 是一个现代 ​JavaScript 应用程序的​ ​静态模块打包工具(module bundler)​。

它主要用于:

将多个模块(JS、CSS、图片、Vue/React 组件等)及其依赖关系分析整合,最终生成优化过的、可在浏览器中运行的静态资源(如 bundle.js、main.css 等)。​=        

通俗理解:

        有一个 ​前端项目,里面有:

  • 一个主 JS 文件:main.js
  • 很多模块:比如工具函数 utils.js、组件 header.js、样式文件 style.css、图片 l.png
  • 你可能还用了 Vue / React / TypeScript / SCSS 等

但这些文件之间 ​有依赖关系,而且浏览器 ​不能直接理解某些高级语法或模块格式​(比如 ES6 模块 import、export、TypeScript、Sass 等)。

这时候就需要一个工具,来:

  1.  ​分析各个文件之间的依赖关系
  2.  把它们打包成一个或多个浏览器能运行的文件(如 bundle.js)​
  3.  ​处理各种资源:JS、CSS、图片、字体等
  4.  ​转换高级语法(如 ES6 → ES5、TypeScript → JS、Sass → CSS)​
  5.  ​优化代码(压缩、Tree-Shaking、代码分割等)​

这个工具,就是 ​Webpack!​

2、模块化的演进过程

        1、script标签
 <script src=""></script>

最原始的通过javaScript文件加载方式,把每一个文件都当成一个模块;

        这种原始方式加载的弊端

  • 全局作用域会存在变量冲突
  • 文件只能按照<script>书写的顺序加载
  • 必须由开发者解决模块和代码库的依赖关系
  • 项目难以维护
        2、commonsJS
require("module");
require("../module.js");
export.dostuff = function(){};
module.exports = someValue;

  服务器端的 NodeJS 遵循 CommonsJS 规范,该规范核心思想是允许模块通过 require 方法来同步加载所需依赖的其它模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。

        优点:

  • 服务器端模块便于重用
  • 简单易用
  • NPM 中已经有非常完善的可以使用的模块包

  缺点:

  • 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
  • 不能非阻塞的并行加载多个模块

      应用:

  • 服务端的 NodeJS
  • Browserify,浏览器端的 CommonsJS 实现,可以使用 NPM 的模块,但是编译打包后的文件体积较大
        3、AMD

Asynchronous Module Definition 规范其实主要一个主要接口 define(id,dependencies,factory);它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行

define("module",["dep1","dep2"],function(d1, d2) {
    return someExportedValue;
});
require(["module","../file.js"],function(module, file){});

    优点:

  • 适合于浏览器的异步加载
  • 可以并行加载多个模块

        缺点:

  • 提高了开发成本,代码阅读和编写比较困难
  • 不符合通用的模块化思想

        应用:

  • RequireJS
        4、CMD

 Commons Module Definition 规范和 AMD 很相似,尽量保持简单,并与 CommonsJS 和NodeJS 的 Modules 规范保持了很大的兼容性。

define(function(require,exports,module){
    var $=require("jquery");
    var spinning=require("./spinning");
    exports.dosomething=...;
    module.exports =...;
});

  优点:

  • 依赖就近,延迟执行
  • 可以很容易在 NodeJS 中运行

        缺点:

  • 依赖 SPM 打包,模块的加载逻辑偏重
        5、ES6模块

   EcmaScript6 标准增加了 JavaScript 语言层面的模块体系定义。 ES6 模块的设计思想是尽量静态化,使编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonsJS 和 AMD 模块,都只能在运行时确定这些东西。

import "jquery";
export function dostuff(){}
module "localModule” {}

    优点:

  • 容易进行静态分析
  • 面向未来的 EcmaScript 标准

        缺点:

  • 原生浏览器端还没有实现该标准
  • 全新的命令,新版的 NodeJs 才支持

3、Vue 与 Webpack 的关系

 vue-cli和 Webpack,从 ​Vue 2.x​ 开始,官方提供了一个非常流行的脚手架工具:​​Vue CLI​,它底层默认使用 Webpack​ 作为模块打包工具,快速搭建一个可运行的 Vue 项目。

Vue CLI 3 / 4 / 5 默认内置了 webpack 配置,一般不需要手动配置 webpack,除非有特殊需求。​​

从 ​Vue 3.x​ 开始,官方还推出了 ​Vite​(一个更快的构建工具,基于 ES modules,不是 webpack),但 ​Webpack 仍然是很多老项目、企业级项目的主要构建工具

4、Vue 项目中的 Webpack        

 使用 Vue CLI 创建项目:

vue create vue-project-test
或
vue init webpack vue-project-test

它会生成一个完整的 Vue + Webpack 项目结构,包括:

  • /src:源码目录
  • /public:静态资源
  • 自动配置的 Webpack(隐藏在 node_modules/.bin/vue-cli-service 中)
  • package.json文件中包含所有要打包的程序模块的版本信息
  • 支持:
    • .vue 单文件组件
    • 热更新
    • dev / build 命令
    • ESLint、Babel、PostCSS 等

运行:

npm run serve   # 开发模式,启动 dev server
npm run build   # 生产构建,打包优化

这些命令背后就是 ​Webpack 在工作,只是 Vue CLI 封装好了,​一般不需要直接接触 webpack.config.js

5、自定义安装webpack

        1、命令:

npm install webpack -g
npm install webpack-cli -g

2、安装测试

webpack -v
webpack-cli -v

3、配置

                创建 webpack.config.js 配置文件

  • entry:入口文件,指定 WebPack 用哪个文件作为项目的入口
  • output:输出,指定WebPack 把处理完成的文件放置到指定路径
  • module:模块,用于处理各种类型的文件
  • plugins:插件,如:热更新、代码重用等
  • resolve:设置路径指向
  • watch:监听,用于设置文件改动后直接打包
    module.exports={
        entry: "",
        output: {
            path: "",
            filename: ""
        },
        module: {
            loaders: [
                {test:/\.js$/,loader:""}
            ]
        },
        plugins: {},
        resolve: {},
        watch: true
    }

6、使用webpack

    1、创建项目

        2、在项目中创建modules目录,用于放JS模块等资源文件

        3、在modules目录下创建.js模块文件,用于编写js代码

//文件名为hello.js
//暴露一个方法:hello
exports.hello= function() {
    document.write("
Hello WebPack
"); }

        4、在modules下创建一个名为 main.js 的入口文件,用于打包时设置 entry 属性

//require导入一个块,就可以调用这个模块中的方法了
var hello =require("./hello");  //导入模块的文件名
hello.hello();

        5、在项目目录下创建 webpack.config.js 配置文件,

module.exports = {
    entry: "./modules/main.js",  //入口文件位置
    output: {
        filename: "./js/bundle.js"  //输出文件位置已经名称
    }
}

        6、使用 webpack 命令打包

                命令行直接输入webpack