前端工程化 -- webpack

前端工程化 – webpack

webpack是一个用于JavaScript应用程序的静态打包工具当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图,将项目所需的每一个模块组合成一个或多个bundles(均为静态资源)用于展示内容。

静态模块:指开发阶段,可以被webpack直接引用的资源(可以直接被获取打包进bundle.js的资源)

webpack 处理应用程序时,它会在内部构建一个依赖图,此依赖图对应映射到项目所需的每个模块(不再局限 js文件),并生成一个或多个 bundle

核心概念

  • 入口(entry)

入口起点(entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。默认值是 ./src/index.js,在webpack.config.js中配置entry属性来指定入口起点。

module.exports = {
  entry: './path/to/my/entry/file.js',
};
  • 输出(output)

output属性告诉webpack在哪里输出所创建的bundle,以及如何命名文件。主要输出文件的默认值是./dist/main.js,其他生成文件默认放置在./dist文件夹中。

const path = require('path');

module.exports = {
 entry: './path/to/my/entry/file.js',
 output: {
   path: path.resolve(__dirname, 'dist'),
   filename: 'my-first-webpack.bundle.js',
 },
};
  • loader

webpack只能理解javascript和JSON文件,而loader让webpack能处理其他类型文件,并转换为有效模块,供程序使用以及被添加到依赖图中。

loader的两个属性:

  1. test:识别哪些文件会被转换
  2. use:定义在进行转换时,应该使用哪个loader
const path = require('path');

module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
};
  • 插件(plugin)

用于执行范围更广的任务。包括:打包优化、资源管理、注入环境变量

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建一个插件实例

const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 用于访问内置插件

module.exports = {
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
  • 模式(mode)

通过选择 development, productionnone 之中的一个,来设置 mode 参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production

选项说明

选项描述
development开发模式,打包更加快速,省去代码优化步骤
production生产模式,打包较慢,会开启tree-shaking和压缩代码
none不适用任何默认优化选项
module.exports = {
 mode: 'production',
};
  • 浏览器兼容性(browser compatibility)

Webpack 支持所有符合 ES5 标准 的浏览器(不支持 IE8 及以下版本)。webpack 的 import()require.ensure() 需要 Promise。如果你想要支持旧版本浏览器,在使用这些表达式之前,还需要 提前加载 polyfill

  • 环境(envrironment)

Webpack 5 运行于 Node.js v10.13.0+ 的版本

webpack的能力

  • 代码编译能力,提高效率,解决浏览器兼容问题,将es6+的语法、typescript的脚本编译为es5低版本代码
  • 模块整合能力,提高性能,可维护性,解决浏览器频繁请求文件的问题(将多个模块文件打包成一个 bundle)
  • 万物皆可模块化,项目维护性增强,支持不同种类的前端模块类型,统一的模块化方案,所有资源文件的加载都可以通过代码控制

webpack的构建流程

  1. 初始化流程:从配置文件和 Shell 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数
  2. 编译构建流程:从 Entry 出发,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行编译处理
  3. 输出流程:对编译后的 Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统

webpack基础(配置)

简单配置:
  • Webpack常规配置项有哪些?
  • 常用Loader有哪些?如何配置?
  • 常用插件(Plugin)有哪些?如何配置?
  • Babel如何配置?Babel插件如何使用?

安装依赖

npm install webpack webpack-cli -D

运行npx webpack,启动打包

配置文件 webpack.config.js

const path = require('path')

module.exports = {
  mode: 'development', // 模式
  entry: './src/index.js', // 打包入口地址
  output: {
    filename: 'bundle.js', // 输出文件名
    path: path.join(__dirname, 'dist') // 输出文件目录
  }
}

Loader

webpack默认支持处理JS与JSON文件,其他类型都处理不了,因此必须借助Loader来对不同类型的文件进行处理。

例如:安装css-loader来处理CSS

npm install css-loader -D

配置资源加载模块:(通过选项test和use来匹配)

const path = require('path')

module.exports = {
  mode: 'development', // 模式
  entry: './src/main.css', // 打包入口地址
  output: {
    filename: 'bundle.css', // 输出文件名
    path: path.join(__dirname, 'dist') // 输出文件目录
  },
  module: { 
    rules: [ // 转换规则
      {
        test: /\.css$/, //匹配所有的 css 文件
        use: 'css-loader' // use: 对应的 Loader 名称
      }
    ]
  }
}

插件

插件贯穿Webpack打包的生命周期,执行不同的任务

如果我想打包后的资源文件,例如:js 或者 css 文件可以自动引入到 Html 中,就需要使用插件 html-webpack-plugin来帮助你完成这个操作

(自动清空打包目录插件:clean-webpack-plugin)

安装插件:

npm install html-webpack-plugin -D

配置插件:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ITEM</title>
<script defer src="bundle.js"></script></head>
<body>
  
</body>
</html>

区分环境

根据本地开发和部署线上,有不同的需求

本地安装croos-env

npm install cross-env -D

在webpack配置文件中获取环境变量:

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

console.log('process.env.NODE_ENV=', process.env.NODE_ENV) // 打印环境变量

const config = {
  entry: './src/index.js', // 打包入口地址
  output: {
    filename: 'bundle.js', // 输出文件名
    path: path.join(__dirname, 'dist') // 输出文件目录
  },
  module: { 
    rules: [
      {
        test: /\.css$/, //匹配所有的 css 文件
        use: 'css-loader' // use: 对应的 Loader 名称
      }
    ]
  },
  plugins:[ // 配置插件
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
}

module.exports = (env, argv) => {
  console.log('argv.mode=',argv.mode) // 打印 mode(模式) 值
  // 这里可以通过不同的模式修改 config 配置
  return config;
}

启动devServer

安装 webpack-dev-server

npm install webpack-dev-server@3.11.2 -D

配置本地服务:

// webpack.config.js
const config = {
  // ...
  devServer: {
    contentBase: path.resolve(__dirname, 'public'), // 静态文件目录
    compress: true, //是否启动压缩 gzip
    port: 8080, // 端口号
    // open:true  // 是否自动打开浏览器
  },
 // ...
}
module.exports = (env, argv) => {
  console.log('argv.mode=',argv.mode) // 打印 mode(模式) 值
  // 这里可以通过不同的模式修改 config 配置
  return config;
}

引入css

需要再安装一个 style-loader 来完成这个功能 npm install style-loader -D

配置loader:

const config = {
  // ...
  module: { 
    rules: [
      {
        test: /\.css$/, //匹配所有的 css 文件
        use: ['style-loader','css-loader']
      }
    ]
  },
  // ...
}

引用样式文件:在入口文件 ./src/index.js 引入样式文件 ./src/main.css

CSS兼容性,引入postcss-loader,自动添加CSS3部分属性的浏览器前缀

引入less和sass

文件类型loader
lessless-loader
sasssass-loader node-sass 或 dart-sass

JS兼容性(Babel)

对JS做兼容处理,让有些不支持新特性的浏览器也能正常运行,常见的方式是将ES6语法转化为ES5。

安装Babel依赖:$ npm install babel-loader @babel/core @babel/preset-env -D

  • babel-loader 使用 Babel 加载 ES2015+ 代码并将其转换为 ES5
  • @babel/core Babel 编译的核心包
  • @babel/preset-env Babel 编译的预设,可以理解为 Babel 插件的超集

配置Babel预设:

// webpack.config.js
// ...
const config = {
  entry: './src/index.js', // 打包入口地址
  output: {
    filename: 'bundle.js', // 输出文件名
    path: path.join(__dirname, 'dist'), // 输出文件目录
  },
  module: { 
    rules: [
      {
        test: /\.js$/i,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-env'
              ],
            }
          }
        ]
      },
    // ...
    ]
  },
  //...
}
// ...

SourceMap配置选择

SourceMap 是一种映射关系,当项目运行后,如果出现错误,我们可以利用 SourceMap 反向定位到源码位置

devtool配置

const config = {
  entry: './src/index.js', // 打包入口地址
  output: {
    filename: 'bundle.js', // 输出文件名
    path: path.join(__dirname, 'dist'), // 输出文件目录
  },
  devtool: 'source-map',
  module: { 
     // ...
  }
  // ...

执行打包后,dist 目录下会生成以 .map 结尾的 SourceMap 文件

模式总结:

devtoolbuildrebuild显示代码SourceMap 文件描述
(none)很快很快无法定位错误
eval很快(cache)编译后定位到文件
source-map很慢很慢源代码定位到行列
eval-source-map很慢一般(cache)编译后有(dataUrl)定位到行列
eval-cheap-source-map一般快(cache)编译后有(dataUrl)定位到行
eval-cheap-module-source-map快(cache)源代码有(dataUrl)定位到行
inline-source-map很慢很慢源代码有(dataUrl)定位到行列
hidden-source-map很慢很慢源代码无法定位错误
nosource-source-map很慢很慢源代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值