导读

看一下这个视频,你会对webpack有更深刻的认识:小满Vue3(第四十三章 webpack 从0到1 构建vue3

只能说是了解一下吧,毕竟学的Vue3,使用vite构建会更方便的多

实际开发中会使命令行工具(俗称 脚手架)一键生成带有 webpack 的项目

  • 开箱即用,所有 webpack 配置项都是现成的!
  • 我们只需要知道 webpack 中的基本概念即可!

脚手架(英文名:scaffolding)是一种代码生成工具,它可以快速创建一个项目的基本结构和初始代码,使得开发者可以更快地开始项目开发。脚手架通常包含了一些预设的配置和工具链,可以帮助开发者管理依赖、构建代码、运行测试等常见任务。

常见的前端脚手架包括Vue CLI、Create React App、Angular CLI等,它们都是基于Webpack等工具构建而成的。这些脚手架在项目创建时会自动安装和配置Webpack等工具,并提供了一些默认的Webpack配置,可以帮助开发者快速构建和打包应用程序。

需要注意的是,脚手架并不是替代Webpack的工具,它们是建立在Webpack等工具的基础之上的。 脚手架提供了更高层次的抽象和封装,使得开发者可以更快速、更方便地使用Webpack等工具来构建应用程序。但是,如果需要对Webpack进行更深入的定制和配置,则仍然需要直接使用Webpack。

因此,可以将脚手架看作是一种便捷的开发工具,可以帮助开发者快速创建和构建应用程序,但是在某些情况下可能需要对其进行一定的定制和配置,或者直接使用Webpack等工具来完成更复杂的构建任务。


Vite可以被看作是一个脚手架工具,但它比传统的脚手架工具更加轻量级和灵活,而且它的设计思想和实现方式与脚手架有所不同。

传统的脚手架工具通常会提供一套预设的项目结构和配置,同时也会包含一些预设的工具链和插件,用于管理依赖、构建代码、运行测试等常见任务。开发者可以通过脚手架工具来快速创建和初始化一个项目,然后基于这个项目进行开发。

而Vite则采用了一种基于浏览器原生ES模块的开发模式,它可以直接在浏览器中运行代码,无需进行打包和编译操作。Vite提供了一种更轻量级和灵活的开发方式,开发者可以根据自己的需求来选择和配置需要的工具和插件,从而更加灵活地构建应用程序。

因此,Vite可以被看作是一种新型的脚手架工具,它提供了更加轻量级和灵活的开发体验,同时也支持热更新、按需编译等功能,可以帮助开发者更高效地构建现代化的Web应用程序。

现在,前端也工程化了

前端工程化的基本概念

在前端开发中,遵循模块化、组件化、规范化和自动化这四个现代化可以提高代码可维护性和团队协作效率。最终实现这四个现代化所需要的工具、技术流程以及经验等都要进行规范化和标准化,这就是前端工程化。

其中:

  • 模块化:将复杂的代码分割成小部分,并按照依赖关系构建应用程序。
  • 组件化:除了HTML、CSS和JavaScript外,还需考虑结构与行为上功能单一且能被多次使用的UI元素。
  • 规范话:需要统一文件夹目录结构、编码方式等方面达到项目领域内产品生产信息标准共识。
  • 自动话: 使得诸如打包压缩等日常操作变得更加轻松。

前端工程化带来的好处

前端工程会让你在从创建到测试到部署各阶段不再像简单拽一些第三方库那样粗暴地完成项目开发任务,而是要考虑各个因素并实现前端4M(Modularity, Componentization, Standardization, Automation),以此提升软件质量与客户价值并减少协调沟通成本。

  • 先使前端开发自己成体系,从而覆盖了项目工程化的方方面面。
  • 最大限度提高效率,降低技术选型或前后端联调等带来的协调沟通成本。通过规范化和标准化实现极致开发体验。

前端工程化解决方案

当前主流的前端工程解决方案是Webpack,它是一个模块打包器。另一个备受关注并逐渐取代早期的解决方案 Grant 和 Gap 的框架为 Parcel.

虽然Grant和Gap已经边缘化了,但有些项目仍会用到他们;值得一提的是Parcel还需要时间进一步检验稳健性能以及生态圈质量上 。

掌握 Webpack 的使用并深入理解前端工程化概念对于在企业级开发中取得成功至关重要。

快速上手(快速食用)

Webpack是一个模块打包器,它可以将JavaScript、CSS、图片等资源打包成静态文件,并支持部署到生产环境。

基本步骤

使用Webpack的基本步骤如下:

  1. 在项目中安装Webpack:npm install webpack --save-dev
  2. 创建一个Webpack配置文件:webpack.config.js
  3. 配置入口(entry)和输出(output)路径
  4. 配置加载器(loaders),例如babel-loader用于编译ES6语法
  5. 可选配置插件(plugins),例如UglifyPlugin用于压缩代码
  6. 运行webpack命令来生 成打包后的静态资源。

示例:

// webpack.config.js  
const path = require('path');  
​  
module.exports = {  
  entry: './src/index.js',  
  output: {  
    filename: 'bundle.js',  
    path: path.resolve(__dirname, 'dist'),  
  },  
  module: {  
    rules: [  
      { test: /\.js$/, exclude:/node_modules/, use: 'babel-loader' },  
      { test:/\.css$/, use:['style-loader', 'css-loader'] }  
    ]  
  },   
};

然后在终端(命令提示符)上执行 npx webpack 命令即可生成打包好的代码。 可否解释下上面的操作 上述操作基本上是在创建一个Webpack的配置文件,然后使用该配置文件告诉Webpack需要如何打包你的代码。

具体来说:

  1. 第一步是安装Webpack和相关loader或plugin,这些可以根据项目需求进行选择安装。例如 npm install webpack babel-loader --save-dev 表示同时安装了webpack和用于编译ES6语法的babel loader。
  2. 创建一个名为webpack.config.js 的Webpack配置文件,并在其中定义入口(entry)、输出(output)路径等基本选项。
  3. 在module.rules中定义各种解析规则(loader),例如针对不同类型的文件应使用哪些loader进行转换处理等。
  4. 如果需要进一步优化打包结果,则可以添加与插件(plugins)有关的配置,这些通常用于生成source map、压缩JS/CSS代码、提取公共部分(CommonChunkPlugin)等操作(可选)。
  5. 最后,在终端上运行相应指令以调用Webpack实现自动化构建。

利用package.json启动webpack

可以在package.json文件中定义script脚本来方便地运行前端项目的打包命令。例如,在scripts对象中添加以下配置:

"scripts": {  
  "dev": "webpack --mode development",  
  "build": "webpack --mode production"  
}

这样,我们就可以通过 npm run devnpm run build 命令分别执行开发环境和生产环境下的Webpack命令,并不必手动输入复杂的指令。

同时, package.json 还能够存储一些其他项比如元信息(描述、版本号等)与包自身信息(作者、license之类)以及其他工具库(如 jest, eslint等)的扩展属性做约束管理使其更易于维护。

两种启动方式的比较

根据具体的项目需求和情况,选择合适的启动方式是非常重要的。在简单的项目中,使用package.json中的脚本定义可能更为方便;而在复杂的项目中,使用webpack命令启动项目可能更为灵活和方便。

  • 在一些简单的项目中,使用package.json中的脚本定义可以更为方便。例如,在一个简单的React项目中,我们可以将启动开发服务器的命令定义在package.json的scripts字段中:
        {  
          "name": "my-react-app",  
          "version": "1.0.0",  
          "scripts": {  
            "start": "react-scripts start"  
          },  
          "dependencies": {  
            "react": "^17.0.2",  
            "react-dom": "^17.0.2"  
          },  
          "devDependencies": {  
            "react-scripts": "^4.0.3"  
          }  
        }
    
    然后,我们可以使用npm run start命令启动开发服务器,非常方便。
  • 相比之下,使用webpack命令来启动项目,可以更方便地管理和使用不同环境的webpack配置。通常情况下,我们会将不同环境的webpack配置文件分别命名为webpack.config.js、webpack.config.dev.js、webpack.config.prod.js等,并在启动命令中指定对应的配置文件,例如:
        webpack --config webpack.config.dev.js  
        webpack --config webpack.config.prod.js
    
    这样做的好处是,可以更方便地管理和使用不同环境的webpack配置,而且不会让package.json文件变得过于复杂和难以维护。同时,使用webpack命令也可以方便地进行其他操作,例如查看webpack的版本信息、查看webpack的帮助信息等。 总之,使用webpack命令来启动项目,可以更方便地管理和使用不同环境的webpack配置,同时也可以方便地进行其他操作,提高开发效率和便捷性。

Webpack 初步介绍

  • Webpack 是前端项目工程化中的解决方案,提供模块打包、代码优化、浏览器兼容性和性能优化等功能。
  • 使用 Webpack 能够提高前端开发效率和可维护性,使程序员专注于具体功能的实现而不必为浏览器兼容等问题担忧。
  • “打包”或“构建”是企业级前端项目开发中重要概念,指使用 Webpack 对项目进行一系列处理以达到部署要求。
  • 总之,Webpack 是一个强大的现代化工具,用于改进前端开发。

webpack.config.js

Tip:开发环境打包快体积大,生产环境打包慢体积小(压缩、混淆等)

Webpack的打包方式和环境可以通过配置文件webpack.config.js来定义。具体来说还有其他的设置项:

  1. 可以通过mode选项将Webpack的工作模式设置为development或production,从而指定其是用于开发还是生产环境。
  2. 配置入口(entry)和输出(output)路径,告诉Webpack需要打包哪些代码,并把它们生成到哪个目录中。
  3. 添加loaders(加载器),例如babel-loader用于编译ES6语法、sass-loader用于处理Sass样式等;
  4. 同时添加plugins(插件)进行优化配置。如:UglifyPlugin会压缩JS文件大小,使用插件CommonsChunkPlugin则能够将公共代码提取出来避免多次请求同一个脚本;
  5. 配置其他参数与选项,例如输入日志、启动source-map调试功能等。

在快速上手的示例中尽管并未明确设置打包所属的环境变量mode, 然而它已经默认 给出了一套适合基础应用层 和得到最佳表现 建议设定 的webpack推荐方案;根据实际需求扩展即可

为了综合展示Webpack配置文件的常见选项和参数,以下是一个基本的webpack.config.js示例:

const path = require('path');  
const HtmlWebpackPlugin = require('html-webpack-plugin');  
​  
module.exports = {  
  mode: 'development',   
  entry: './src/index.js',  
  output: {  
    filename: '[name].[contenthash].js',  
    path: path.resolve(__dirname, 'dist'),  
  },  
  devtool: 'inline-source-map',  
  module: {  
    rules: [  
      { test:/\.js$/, exclude:/node_modules/, use:'babel-loader' },  
      { test:/\.css$/, use:['style-loader', 'css-loader'] }  
    ]  
  },   
   plugins:[  
         new HtmlWebpackPlugin({  
              title:"basic HTML Index", //生成出来的HTML title  
              template:"./src/index.html" //根据哪个模板去生产HTML  
                        }),  
        ],  
};

该配置文件包括以下内容:

  1. 设置工作模式为开发环境。
  2. 将入口文件设定为 src/index.js 文件,并将打包后的资源输出到 dist/ 目录下名称为 [name].[contenthash].js 的文件中;
  3. 设置 source map 方便地调试源码;
  4. 添加使用 Babel 进行 ES6 转换和 CSS 处理工具 style 和 css loader;
  5. 插件部分添加使用HtmlWebpackPlugin自动化创建基础页面逻辑。

Webpack默认约定和自定义配置

默认约定

  • Webpack的默认入口文件为src/index.js
  • Webpack的默认输出文件路径为dist/main.js

自定义配置

Tip

输出的文件是什么呢,就是打包后的文件,比如index.html会打包输出一个main.js,这个main.js能够解决原来可能存在的浏览器兼容问题的语法,记得在原来引入index.html的文件中替换成引入main.js

通过在Webpack配置文件中修改以下节点来实现自定义打包入口与出口:

  • entry: 指定打包的入口
    • 例如,可以使用path.join()方法将src/index.js拼接成完整路径。
  • output: 指定打包的出口
    • 包含了 pathfilename两个属性,其中:
      • path: 输出文件存放路径
        • 如需做路径拼接,则需要使用require()导入Path模块,并调用其join()方法。
      • filename: 输出文件名称

例子:

const path = require('path');  
​  
module.exports = {  
  entry: path.join(__dirname, 'src', 'index.js'),  
  output: {  
    path: path.join(__dirname, 'dist'),   
    filename: 'bundle.js'  
  }  
};

Webpack中的插件

通过安装和配置第三方的插件(总之使用第三方的相关插件或loader等的支持都需要记住手动npm install),可以拓展 webpack 的能力,从而让 webpack 用起来更方便。最常用的webpack 插件有如下两个:

  • webpack-dev-server
    • 类似于 node.js 阶段用到的 nodemon 工具
    • 每当修改了源代码,webpack 会自动进行项目的打包和构建
  • html-webpack-plugin
    • webpack 中的 HTML 插件(类似于一个模板引擎插件)
    • 可以通过此插件自定制 index.html 页面的内容

webpack-dev-server

安装和使用webpack-dev-server需要遵循以下步骤:

  1. 安装webpack-dev-server

使用npm安装webpack-dev-server:

npm install webpack-dev-server --save-dev

  1. 配置webpack.config.js文件
    在webpack.config.js文件中添加devServer配置项,指定webpack-dev-server的相关配置,例如端口号、代理等:
    js const path = require('path'); ​ module.exports = {  // 入口文件  entry: './src/index.js',  // 出口文件  output: {    filename: 'bundle.js',    path: path.resolve(__dirname, 'dist'), },  // devServer配置项  devServer: {    contentBase: path.resolve(__dirname, 'dist'),    port: 8080,    proxy: {      '/api': {        target: 'http://localhost:3000',        pathRewrite: {'^/api' : ''}     }   }, }, };

  2. 在package.json文件中添加启动命令
    在package.json文件中的scripts字段中添加启动命令,例如:

    	"scripts": {
    	  "start": "webpack-dev-server --open --config webpack.config.js"
    	},
    

    其中,--open选项表示自动打开浏览器,--config选项指定webpack配置文件。

  3. 启动webpack-dev-server
    使用npm启动webpack-dev-server:

    npm run start
    

这样就可以启动webpack-dev-server了。启动后,webpack-dev-server会自动监听文件变化并重新编译代码,同时在浏览器中打开网页。如果进行了更改,webpack-dev-server会自动刷新页面以显示最新的更改。

需要注意的是,webpack-dev-server默认将文件存储在内存中,而不是在磁盘上。因此,如果需要在磁盘上生成文件,需要使用webpack的输出配置项。例如,在上面的示例中,输出文件将保存在dist目录中。

html-webpack-plugin

html-webpack-plugin是一个webpack插件,可以自动生成一个HTML文件,并将打包生成的bundle文件自动引入到HTML文件中。使用html-webpack-plugin可以方便地生成HTML文件,同时自动引入打包生成的JS和CSS文件,避免手动修改HTML文件。

下面是使用html-webpack-plugin的步骤:

  1. 安装html-webpack-plugin
    使用npm安装html-webpack-plugin:

    npm install html-webpack-plugin --save-dev
    
  2. 配置webpack.config.js文件
    在webpack.config.js文件中添加html-webpack-plugin的配置项:

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      // 入口文件
      entry: './src/index.js',
      // 出口文件
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      // 插件配置项
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
          filename: 'index.html',
        }),
      ],
    };
    

    其中,HtmlWebpackPlugin的配置项中,template指定HTML模板文件的路径,filename指定生成的HTML文件的名称。

  3. 创建HTML模板文件
    在src目录下创建一个index.html文件,作为HTML模板文件,例如:

    	<html>
    	  <head>
    	    <meta charset="utf-8">
    	    <title>Webpack Demo</title>
    	  </head>
    	  <body>
    	    <div id="app"></div>
    	  </body>
    	</html>
    

    需要注意的是,HTML模板文件中不能手动引入打包生成的JS和CSS文件,由于使用了html-webpack-plugin插件,打包生成的JS和CSS文件会自动引入到HTML文件中。

  4. 执行打包命令
    使用webpack命令执行打包命令:

    webpack --mode development
    

    执行完成后,会在dist目录下生成一个index.html文件,并将打包生成的bundle.js文件自动引入到HTML文件中。
    通过使用html-webpack-plugin插件,可以方便地生成HTML文件,并自动引入打包生成的JS和CSS文件,避免手动修改HTML文件。同时,还可以使用HTML模板文件来控制生成的HTML文件的格式和内容。

这有啥用呢?例如指定首页...

其实这个插件有一个很好的作用比如指定一个html模板复制到项目根目录,那么就可以直接访问主机地址+端口号访问index.html而不需要还指定具体路径,注意的是复制的是模板,模板是可变可插值的而且生成的页面同样是存放在不可见的内存中

自定义devServer节点

使用webpack-dev-server可以在开发过程中快速启动一个开发服务器,支持热重载、自动刷新等功能。下面是配置devServer节点的示例:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // 入口文件
  entry: './src/index.js',
  // 出口文件
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  // 插件配置项
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
  ],
  // 开发服务器配置
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000,
    open: true,
  },
};

上述配置中,devServer节点的配置项说明如下:

  • contentBase:指定开发服务器的根目录,即webpack-dev-server启动时的文件根目录,这里指定为dist目录。
  • compress:启用gzip压缩。
  • port:指定开发服务器的端口号,这里指定为9000。
  • open:启动开发服务器时是否自动打开浏览器。

通过设置devServer节点,可以方便地启动开发服务器并进行开发调试。在执行webpack-dev-server命令时,会根据配置启动开发服务器,自动打开浏览器,并将打包生成的文件放入内存中,实现快速的开发调试。

Webpack中的Loader

在实际开发过程中,webpack默认只能打包处理以.js 后缀名结尾的模块。其他非js 后缀名结尾的模块webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错! loader 加载器的作用: 协助 webpack 打包处理特定的文件模块。比如:

  • css-loader 可以打包处理.css 相关的文件
  • less-loader 可以打包处理 .less 相关的文
  • babel-loader 可以打包处理 webpack 无法处理的高级JS 语法(比如static等,但是呢随着webpack版本升级这些都已被兼容)

Loader的调用过程

先判断是否为js模块,再判断

  • 不是js模块检查是否配置对应的loader;有则调用loader处理无则报错
  • 是js模块检查是否包含高级js语法
    • 是的话,检查是否配置了babel;有则调用loader处理无则报错
    • 否的话webpack直接处理

image-20230330003130840

基本使用(CSS、Less、JS)

以CSS Loader为例(less、js也类似的~),使用Loader的步骤如下:

  1. 安装Loader 使用npm安装Loader,例如安装CSS Loader:

    npm install css-loader --save-dev
    
    1. 在Webpack配置文件中配置Loader 在Webpack配置文件中,使用module.rules配置Loader,例如配置CSS Loader:
        
    
    module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [
              'style-loader',
              'css-loader'
            ]
          }
        ]
      }
    };
    
  2. 使用Loader 在JavaScript文件中,使用import或require引入需要转换的文件,例如:

    import './styles.css';
    

注意事项:

  1. Loader的顺序很重要,Webpack会按照Loader的顺序依次转换文件。因此,如果有多个Loader,要注意它们的顺序。
    • 这里的Loader加载顺序是按从后往前顺序加载的,因为Webpack会先将源文件交给最后一个Loader处理
  2. Loader也可以传递参数,例如CSS Loader可以传递options参数指定一些配置。
  3. Loader也可以使用正则表达式匹配文件。在配置Loader时,可以使用test属性指定需要转换的文件类型。
  4. Loader可以链式调用,例如同时使用CSS Loader和Sass Loader转换CSS和Sass文件:
    {
      test: /\.(css|scss)$/,
      use: [
    	'style-loader',
    	'css-loader',
    	'sass-loader'
      ]
    }
    

打包处理样式表中与 url 路径相关的文件

首先,我们需要了解为什么需要添加参数项。在样式表中,我们可能会用到一些小图片,例如logo.png。如果我们在样式表中引用了太多的小图片,会导致网页发起不必要的网络请求,从而降低网页的加载性能。为了优化网页性能,我们可以把那些小图片转成base 64的格式,这样可以尽量避免不必要的图片请求,提高网页的加载性能。

但并不是所有的图片都适合被转成base 64。只有那些小图片才适合转成base 64,大图片应该直接发起请求。因此,我们需要控制哪些图片需要转换成base 64编码格式,哪些不需要。这时,我们可以使用loader的一个参数项。

1、直接拼接limit参数

loader的URL后面加上一个英文的问号,就代表我们要传递参数了。其中,limit代表一个图片的体积,只有这个图片小于或等于给定值的时候,才会被转成base 64。如果这个图片的体积大于给定值,那么这张图片不会被转成base 64。

2、规范化的option属性设置limit参数

在Webpack中,可以使用url-loader和file-loader来处理样式表中与url路径相关的文件,例如图片、字体等。这些Loader可以将这些文件转换为base64编码或者复制到输出目录中,并返回最终的url路径。下面是一个简单的配置示例:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192, // 小于8KB的文件转换为base64编码
              name: '[name].[hash:8].[ext]', // 输出文件名的格式
              outputPath: 'assets/', // 输出目录的路径
              publicPath: '../assets/', // 最终输出文件中url的前缀,可用于CDN等场景
            },
          },
        ],
      },
    ],
  },
};

在上述配置中,我们使用了url-loader来处理图片、字体等文件。test属性指定需要处理的文件类型,use属性中使用了url-loader,并传递了一些配置项。其中,limit属性指定了文件大小的上限,小于这个上限的文件会被转换为base64编码。name属性指定了输出文件的名称格式,outputPath属性指定了输出文件的目录路径,publicPath属性指定了输出文件中url的前缀,可用于CDN等场景。

除了url-loader以外,还可以使用file-loader来复制文件到输出目录中,例如:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[hash:8].[ext]', // 输出文件名的格式
              outputPath: 'assets/', // 输出目录的路径
              publicPath: '../assets/', // 最终输出文件中url的前缀,可用于CDN等场景
            },
          },
        ],
      },
    ],
  },
};

在上述配置中,我们使用了file-loader来处理图片、字体等文件。test属性指定需要处理的文件类型,use属性中使用了file-loader,并传递了一些配置项。其中,name属性指定了输出文件的名称格式,outputPath属性指定了输出文件的目录路径,publicPath属性指定了输出文件中url的前缀,可用于CDN等场景。

需要注意的是,使用url-loader或file-loader处理文件时,需要在样式表中使用相对路径来引用这些文件,Webpack会自动将这些相对路径转换为最终的url路径。例如,在样式表中引用图片时,可以使用相对路径:

.background {
  background-image: url('../assets/background.jpg');
}

Webpack会将这个相对路径转换为最终的url路径,并输出到最终的输出文件中。

打包处理 js 文件中的高级语法

在Webpack中,可以使用Babel Loader来处理JavaScript文件中的高级语法,例如ES6/ES7语法、JSX语法等。Babel Loader可以将这些高级语法转换为浏览器可识别的语法,并保持兼容性。下面是一个简单的配置示例:

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/preset-react'], // 预设,指定需要支持的语法和特性
              plugins: ['@babel/plugin-proposal-class-properties'], // 插件,用于支持一些新的语法特性
            },
          },
        ],
      },
    ],
  },
};

在上述配置中,我们

  • 使用了Babel Loader来处理JavaScript文件。
  • test属性指定需要处理的文件类型,
  • exclude属性指定需要排除的目录或文件,因为通常来说这些文件不需要经过Webpack的处理。这样可以提高打包的速度和效率。
  • use属性中使用了babel-loader,并传递了一些配置项。其中,
    • presets属性指定了需要支持的语法和特性,例如@babel/preset-env用于支持ES6/ES7语法,@babel/preset-react用于支持JSX语法。
    • plugins属性用于支持一些新的语法特性,例如@babel/plugin-proposal-class-properties用于支持类的属性初始化。需要注意的是,使用Babel Loader时需要同时安装相应的预设和插件。

除了Babel Loader以外,还可以使用TypeScript Loader来处理TypeScript文件,例如:

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true, // 只进行转译,不进行类型检查
            },
          },
        ],
      },
    ],
  },
};

在上述配置中,我们使用了TypeScript Loader来处理TypeScript文件。test属性指定需要处理的文件类型,exclude属性指定需要排除的目录或文件,use属性中使用了ts-loader,并传递了一些配置项。其中,transpileOnly属性指定只进行转译,不进行类型检查,可以加快打包速度。

需要注意的是,使用Babel Loader或TypeScript Loader处理JavaScript文件时,需要在代码中使用相应的语法和特性,否则这些Loader不会生效。例如,在使用Babel Loader处理JavaScript文件时,可以使用ES6/ES7语法:

const sum = (a, b) => {
  return a + b;
};

export default sum;

Webpack会将这些ES6/ES7语法转换为浏览器可识别的语法,并保持兼容性。

Webpack的打包发布

为什么需要打包发布

项目开发完成之后,使用 webpack 对项目进行打包发布的主要原因有以下两点

  • 开发环境下,打包生成的文件存放于内存中,无法获取到最终打包生成的文件
  • 开发环境下,打包生成的文件不会进行代码压缩和性能优化

另外,打包发布也可以将Web应用的代码和资源文件进行加密和混淆,从而保护Web应用的知识产权和安全性。通过打包发布,可以将Web应用的源代码和敏感信息进行隐藏和加密,使得黑客无法轻易获取和破解。

因此,打包发布是Web应用开发中非常重要的一步,它可以将开发环境中的代码和资源文件进行优化和压缩,提高Web应用的性能和加载速度,同时也可以保护Web应用的知识产权和安全性。

简单的实践案例

下面是一个使用Webpack进行打包发布的示例:

假设有一个简单的Web应用,包含一个JavaScript文件和一个CSS文件,以及一些图片等资源文件,目录结构如下:

myapp/
  |- index.html
  |- main.js
  |- main.css
  |- images/
     |- logo.png
     |- banner.jpg

在开发环境中,我们可以直接在HTML文件中引入JavaScript文件和CSS文件,如下所示:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>My App</title>
  <link rel="stylesheet" href="main.css">
</head>
<body>
  <h1>My App</h1>
  <script src="main.js"></script>
</body>
</html>

在生产环境中,为了提高Web应用的性能和加载速度,我们需要将JavaScript文件和CSS文件进行打包和优化。我们可以使用Webpack来完成这个任务。

首先,我们需要安装Webpack和一些相关的Loader和插件,例如使用以下命令来安装:

npm install webpack webpack-cli css-loader style-loader file-loader image-webpack-loader html-webpack-plugin -D

然后,我们需要创建一个Webpack的配置文件,例如在myapp目录下创建一个名为webpack.config.js的文件,内容如下:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'images/',
              publicPath: 'images/'
            }
          },
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false,
              },
              pngquant: {
                quality: [0.65, 0.90],
                speed: 4
              },
              gifsicle: {
                interlaced: false,
              },
              webp: {
                quality: 75
              }
            }
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'My App',
      template: 'index.html'
    })
  ]
};

这个配置文件的作用是告诉Webpack需要打包哪些文件和如何处理这些文件。具体来说,它指定了入口文件为main.js,输出文件为dist/bundle.js,使用了css-loader和style-loader来处理CSS文件,使用了file-loader和image-webpack-loader来处理图片等资源文件,使用了html-webpack-plugin来生成HTML文件。

最后,我们可以在命令行中执行Webpack打包命令,例如使用以下命令来进行打包:

webpack --mode production

但是在实际项目中,我们通常会在package.json文件中添加一个build脚本,然后直接运行build命令来进行打包发布。

具体来说,我们可以在package.json文件中添加如下的配置:

{
  "name": "myapp",
  "version": "1.0.0",
  "scripts": {
    "build": "webpack --mode production"
  },
  "dependencies": {
    "webpack": "^5.33.2",
    "webpack-cli": "^4.7.2",
    "css-loader": "^6.4.0",
    "style-loader": "^3.3.1",
    "file-loader": "^6.2.0",
    "image-webpack-loader": "^8.0.0",
    "html-webpack-plugin": "^5.5.0"
  }
}

在这个配置中,我们定义了一个名为build的脚本,它会自动执行Webpack打包命令,并指定了Webpack的打包模式为production。在运行build命令时,npm会自动查找package.json文件中的脚本配置,并执行对应的命令。

然后,我们可以在命令行中运行以下命令来进行打包发布:

npm run build

运行完毕后,Webpack会自动将所有需要打包的文件进行处理和打包,然后输出到dist目录中。在dist目录中,可以看到打包后的文件和目录结构,包括bundle.js、main.css、logo.png、banner.jpg等文件,以及Web应用所需的index.html文件等。

通过使用npm脚本来运行Webpack打包命令,我们可以更方便地进行打包发布,并且可以避免手动输入复杂的命令行参数。同时,我们也可以在脚本中添加其他的构建步骤和任务,例如对代码进行Lint检查、运行单元测试等,以进一步提高代码的质量和可维护性。

最后,我们可以将dist目录中的文件和目录结构部署到Web服务器或者其他需要发布的地方,例如使用FTP上传到远程服务器等。通过打包发布,我们可以将Web应用的代码和资源文件进行优化和压缩,提高Web应用的性能和加载速度,同时也可以保护Web应用的知识产权和安全性。

SourceMap

Webpack提供了SourceMap功能,可以将打包后的JavaScript代码映射回原始的源代码,从而方便进行调试和定位错误。

具体来说,SourceMap是一种映射关系,它将打包后的JavaScript代码中的每一行和每一列,都映射回源代码中的对应位置。当在浏览器中调试JavaScript代码时,可以使用SourceMap将错误信息和调试信息映射回原始的源代码中,从而方便定位问题。

使用Webpack生成SourceMap非常简单,只需在配置文件中添加devtool选项即可。

例如,在之前的示例中,可以将webpack.config.js文件中的devtool选项设置为eval-source-map,如下所示:

module.exports = {
  // ...其他配置...
  devtool: 'eval-source-map'
};

在这个配置中,我们使用了eval-source-map选项来生成SourceMap。这个选项可以在打包后的JavaScript文件中添加一个特殊的注释,用于指示浏览器如何加载和解析SourceMap。具体来说,这个注释会被添加到打包后的JavaScript文件的第一行,其格式如下所示:

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzI...(省略后面的内容)

这个注释中的内容是一个Base64编码的JSON字符串,它包含了源代码和打包后的代码之间的映射关系。在浏览器中加载打包后的JavaScript时,会自动解析这个注释,并使用其中的映射关系来将错误信息和调试信息映射回原始的源代码中。

需要注意的是,生成SourceMap会增加打包时间和文件大小,因此在生产环境中不建议开启。一般情况下,我们可以在开发环境中开启SourceMap,以方便调试和定位问题;在生产环境中关闭SourceMap,以减少文件大小和优化性能。

小结如下

  • 开发环境下:

    • 建议把 devtool 的值设置为 eval-source-map
    • 好处:可以精准定位到具体的错误行
  • 生产环境下:

    • 建议关闭 Source Map 或将 devtool 的值设置为 nosources-source-map(只显示行数不暴露源码)
    • 好处:防止源码泄露,提高网站的安全性