likes
comments
collection
share

🥙前端小白快速入门webpack指南

作者站长头像
站长
· 阅读数 22

webpack作为目前前端最流行的构建工具,作为前端程序员,掌握构建工具的基本使用我认为是必要的,那么这篇文章会带领大家入门webpack~

一、什么是webpack?

概念:webpack是前端工程化的具体解决方案。

主要功能:它提供了有好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端JavaScript的兼容性、性能优化等强大的功能。

好处:提供了开发效率和代码的可维护性

二、webpack基本使用

安装

npm install webpack@5.42.1 webpack-cli@4.7.2 -D

在项目中配置webpack

  1. 在项目根目录创建名为webpack.config.js的webpack配置文件,并初始化如下的基本配置:
module.exports = {
    mode: 'development' // mode用来指定构建模式,可选值有development和production
}
// development适用于开发环境,不会对打包生成的文件进行代码压缩和性能优化,打包速度快,
//适合在开发阶段使用。
  1. 在package.json的script节点下,新增dev脚本如下:
"script":{
    "dev": "webpack" // script节点下的脚本,可以通过npm run 执行,例如npm run dev,就会启动项目。
}

等等,如何生成package.json文件呢?在项目终端中运行命令npm init -y即可

webpack.config.js文件的作用

webpack.config.js是webpack的配置文件。webpack在真正开始打包构建之前,会先读取这个配置文件,从而基于更定的配置,给项目进行打包。

webpack中的默认约定

在webpack4.x和5.x的版本中,有如下的默认约定:

  1. 默认的打包入口文件为src ->index.js
  2. 默认的输出文件路径为dist ->main.js

这个约定是可以修改的。

自定义打包的入口与出口

在webpack.config.js配置文件中,通过entry节点指定打包的入口,通过output节点指定打包的出口。

const path = require('path') // 导入node.js中专门操作路径的模块
modeule.exports = {
    entry:path.join(__dirname,'./src/index1.js'), // 打包入口文件的路径
    output:{
        path: path.join(__dirname,'/dist'), // 输出文件的存放路径
        filename: 'bundle.js' // 输出文件的名称
    }
}

三、webpack中的插件

通过安装和配置第三方的插件,可以拓展webpack的能力,从而让webpack用起来更方便~

插件1:webpack-dev-server

作用:每当我们修改了源代码,webpack会自动化进行项目的打包和构建

安装webpack-dev-server

npm install webpack-dev-server@3.11.2 -D

配置webpack-dev-server

修改package.json ->scripts中的dev命令

"scripts": {
    "dev": "webpack serve"
}
// 再次运行npm run dev,访问localhost:8080即可
// webpack-dev-server会启动一个实时打包的http服务器

使用webpack-dev-server插件打包过后的文件是放在内存中的~

插件2:html-webpack-plugin

作用:

  1. 通过HTML插件复制到项目根目录中的index.html界面,也被放到内存中
  2. HTML插件在生成的index.html页面,自动注入了打包的bundle.js文件

安装html-webpack-plugin

npm install html-webpack-plugin@5.3.2 -D

配置html-webpack-plugin

// 1.导入HTML插件,得到一个构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2.创建HTML插件的实例对象
const htmlPlugin = new HtmlPlugin({
    template: './src/index.html',// 指定原文件的存放路径
    filename: './index.html'// 指定生成的文件的存放路径
})
module.exoports = {
    mode:development,
    plugins:[htmlPlugin], // 3. 通过plugins节点,使htmlPlugin插件生效
}

devServer节点

可以通过devServer节点对webpack-dev-server插件进行更多的配置~

devServer: {
    open: true, // 初次打包后,自动打开浏览器
    host: '127.0.0.1', // 实时打包所使用的主机地址
    port: 80, // 实时打包使用的端口号
    // 在http协议中,如果端口号是80可以被省略
}
// 修改配置,必须重启打包的服务器

四、webpack中的loader

在实际开发过程中,webpack默认只能打包处理以.js后缀名结尾的模块。其他非.js后缀名结尾的模块,webpack默认处理不了,需要调用loader加载器才可以正常打包,否则会报错!常见的loader有css-loader,less-loader,babel-loader等。

打包处理css文件

运行npm i style-loader@3.0.0 css-loader@5.2.6 -D命令,安装处理css文件的loader 在webpack.config.js的moule ->rules数组中进行配置

module:  { // 所有第三方文件模块的匹配规则
    rules:  [ // 文件后缀名的匹配规则
        {test: /\.css$/,use:['style-loader','css-loader'] }
    ]
}
/*
其中,test表示匹配的文件类型,use表示对应要调用的loader
注意:
use数组中指定的loader顺序是固定的
多个loader的调用顺序是:从后往前
*/

打包流程:

  1. webpack默认只能打包处理.js结尾的文件,处理不了其他后缀的文件。
  2. 由于代码中包含index.css文件,因此webpack默认处理不了。
  3. 当webpack发现某个文件处理不了的时候,会查找webpack.config.js这个配置文件,看module.rules数组中,是否配置了对应的loader加载器。
  4. webpack把index.css这个文件,先转交给最后一个loader进行处理(先转交给css-loader)。
  5. 当css-loader处理完毕之后,转交给下一个loader(转交给style-loader)。
  6. 当style-loader处理完毕之后,发现没有下一个loader了,于是就把处理的结果,转交给webpack。
  7. webpack把style-loader处理的结果,合并到/dist/bundle.js中,最终生成打包好的文件。

打包处理less文件

sass,stylus文件打包处理方式一致,这里就以less文件为例

  1. 运行npm i less-loader@10.0.1 less@4.1.1 -D命令
  2. 在webpack.config.js的module ->rules数组中,添加loader规则如下:
module:  { // 所有第三方文件模块的匹配规则
    rules:  [ // 文件后缀名的匹配规则
        {test: /\.less$/,use:['style-loader','css-loader','less-loader'] }
    ]
}

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

  1. 运行npm i url-loader@4.1.1 file-loader@6.2.0 -D命令
  2. 在webpack.config.js的module ->rules数组中,添加loader规则如下:
module:  { // 所有第三方文件模块的匹配规则
    rules:  [ // 文件后缀名的匹配规则
        {test: /\.jpg|png|gif$/,use: 'url-loader?limit=22229' }
    ]
}
/* ?之后的是loader的参数项,limit用来指定图片的大小,单位是字节,
只有<=limit大小的图片,才会被转为base64格式的图片
*/

打包处理ES6+语法

对于一些高级的JS语法,webpack也无法处理,我们需要借助于babel-loader进行打包处理。

  1. 运行npm i babel-loader@8.2.2 babel/core@7.14.6 @babel/plugin-proposal-decorator@7.14.5 -D命令
  2. 在webpack.config.js的module ->rules数组中,添加loader规则如下:
module:  { // 所有第三方文件模块的匹配规则
    rules:  [ // 文件后缀名的匹配规则
        {test: /\.js$/,use: 'babel-loader',exclude: /node-modules/ }
    ]
}
/* ?之后的是loader的参数项,limit用来指定图片的大小,单位是字节,
只有<=limit大小的图片,才会被转为base64格式的图片
*/
  1. 在项目根目录下,创建名为babel.config.js的配置文件,定义Babel的配置项如下:
module.exports = {
    // 声明babel可用的插件
    plugins: [['@babel/plugin-proposal-decorators',{legacy:true }]]
}

五、打包发布

为了让项目能够在生产环境中高性能的运行,因此需要对项目进行打包发布。 在package.json文件的scripts节点下,新增的build命令如下:

"scripts": { 
    "dev": "webpack serve",// 开发环境中,运行dev命令
    "build": "webpack --mode production"// 项目发布时,运行build命令
}
/* mode是一个参数项,用来指定webpack的运行模式,production代表生产环境,
会对打包生成的文件进行代码压缩和性能优化。
*/

把图片文件统一生成到image目录下

修改webpack.config.js的url-loader配置项,新增outputPath选项即可指定图片文件的输出路径

{test: /\.jpg|png|gif$/,use: 'url-loader?limit=22229&outputPath=images' }

实现自动清理目录下的旧文件

  1. 安装配置clean-webpack-plugin插件 npm install clean-webpack-plugin@3.0.0 -D
  2. 按需导入插件,得到插件的构造函数过后,创建插件的实例对象
const {CleanWepackPlugin} = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()
  1. 把创插件实例对象,挂载到plugins节点中
plugins: [htmlPlugin,cleanPlugin],// 挂载插件

六、Source Map

Source Map就是一个信息文件,里面存储着位置信息,也就是说,Source Map文件中存储着压缩混淆后的代码所对应转换前的位置,有了它,极大的方便后面的调试。 开发环境下默认生成的Source Map,记录的是生成代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。 如何配置呢?

定位行数且暴露源码

只需要在webpack.congif.js中添加如下配置即可

moduleexports = {
    mode: 'development',
    devtool: 'eval-source-map',// 此选项生成的Source Map能够保证报错行数与源代码行数保持一致。
}

在发布的时候尽量关闭Source Map或者把devtool的值设置为nosoures-source-map, 这样能够防止原始代码通过Source Map的形式暴露给别有所图之人,更安全。

只定位行数不暴露源码

如果只想定位报错的具体行数,且不想暴露源码,可以添加如下配置:

moduleexports = {
    mode: 'development',
    devtool: 'nosources-source-map',// 只定位报错行数
}

Source Map最佳实践

  1. 开发环境下:
  • 建议把devtool的值设置为eval-source-map
    
  1. 生厂环境下:
  • 建议把devtool的值设置为nosources-source-map或关闭Source Map。
    

七、webpack使用小技巧

使用@

@表示从src代码源目录,从外往里查找。尽量避免使用../../从里往外找 但使用@之前需要在webpack.confjg.js中添加如下配置:

moduleexports = {
    resolve:{
        alias:{
            '@': path.join(__dirname, './src/')
        }
    }
}

最后