前端工程化与webpack(二)

简介: 前端工程化与webpack(二)

4webpack中的loader

4.1loader概述

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

loader加载器的作用:

协助webpack打包处理特定的文件模块。

比如:

css-loader 可以打包处理 .css 相关的文件

less-loader 可以打包处理 .less相关的文件

babel-loader 可以打包处理webpack无法处理的高级JS语法

4.2loader的调用过程

4.3打包处理css文件

4.3.1安装处理css文件的loader

npm i style-loader css-loader -D

4.3.2配置

在 webpack.config.js 的 module -> rules 数组中,添加loader规则如下:

rules:[{
  test:/\.css$/, use:['style-loader', 'css-loader']
 }]

其中,test表示匹配的文件类型,use表示对应要调用的 loader

注意:

use数组中指定的loader顺序是固定的

多个loader的调用顺序是:从后往前调用

配置后的 webpack.config.js

//导入html-webpack-plugin插件 得到插件的构造函数
const HtmlPlugin = require('html-webpack-plugin')
// new构造函数创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
    // 指定要复制哪个页面
    template: './src/index.html',
    // 指定复制出来的文件名和存放路径
    filename: './index.html'
})
// 使用Node.js中的导出语法,向外导出一个webpack的配置对象
module.exports = {
    // 代表webpack运行的模式,可选值有两个development和production
    mode: 'development',
    // 插件的数组 将来webpack在运行时会加载并调用这些插件
    plugins: [htmlPlugin],
    devServer: {
        // 首次打包成功后自动打开浏览器
        open:true,
        // 在http协议中如果端口号为80可以省略
        port:8080,
        // 指定主机运行的地址
        host:'127.0.0.1' 
    },
    module: {
        rules:[{
            test:/\.css$/, use:['style-loader', 'css-loader']
        }]
    }
}

4.3.3配置完成后就可以导入css样式

在index.js文件中:

// 导入样式,在webpack中,一切皆模块,都可以通过es6导入语法进行导入和使用
import './css/index.css'

4.3.4过程解释

4.4打包处理less文件

4.4.1安装处理less文件的loader

npm i less-loader less -

4.4.2配置

在webpack.confing.js文件中的module->rules数组中添加:

module: {
        rules:[
            {test:/\.css$/, use:['style-loader', 'css-loader']},
            {test:/\.less$/, use:['style-loader', 'css-loader', 'less-loader']}
        ]
    }

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

4.5.1安装

npm i url-loader file-loader -D

4.5.2配置

在webpack.config.js 的 module -> rules数组中,添加loader规则如下︰

module: { //所有第三方文件模块的匹配规则
  rules: [ //文件后缀名的匹配规则
    { test: /\.jpg|png|gif$/,use: 'url-loader?limit=22229'},
  ]
}

其中 ? 之后的是loader的参数项:

limit用来指定图片的大小,单位是字节( byte)

只有≤limit 大小的图片,才会被转为base64格式的图片

补充:小图片适合转成base64,大图片不合适,转成base64图片体积会变大

4.5.3使用js给img标签导入图片

<!-- 需求:把 /src/images/01.jpg 设置给src属性 -->
    <img src="" alt="" class="box">
// 导入图片,得到图片文件
import i from './images/01.jpg'
// 给img标签的src动态赋值
$('.box').attr( 'src', i )

4.5.4loader的另一种配置方式(带参数的loader)

module: { //所有第三方文件模块的匹配规则
  rules: [ //文件后缀名的匹配规则
    { 
      test: /\.jpg|png|gif$/,
      use: {
        //通过loader属性指定调用的loader
        loader: 'url-loader',
        //通过option属性指定参数
        options: {
          limit: 22229
        }
      }
    }
  ]
}

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

webpack.只能打包处理一部分高级的JavaScript语法。对于那些webpack 无法处理的高级js语法,需要借助于babel-loader进行打包处理。

例如:

class Person {
  //webpack无法处理静态属性这个高级语法
  static info = 'person info'
}
console.log( Person.info )

4.6.1安装

npm i babel-loader @babel/core @babel/plugin-proposal-class-properties -D

4.6.2配置

// 使用babel-loader处理高级的js语法
{
  test:/\.js$/, 
  // 注意:必须使用exclude排除指定项;因为node_modules目录下的第三方包不需要被打包
  exclude: /node_modules/,
  use: {
    loader: 'babel-loader',
    options: {
       // 声明babel可用插件
       // 此插件用来转化class中的高级语法
        plugins: ['@babel/plugin-proposal-class-properties']
    }
  } 
}

5打包发布

5.1为什么要打包发布

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

开发环境下,打包生成的文件存放于内存中,无法获取到最终打包生成的文件

开发环境下,打包生成的文件不会进行代码压缩和性能优化

5.2配置webpack的打包发布

在package.json文件的scripts节点下,新增build命令如下:

"scripts" : {
  "dev" : "webpack serve",  //开发环境中,运行
  "build": "webpack --mode production"  //项目发布时,运行 build命令
}

–model是一个参数项,用来指定webpack的运行模式。production代表生产环境,会对打包生成的文件进行代码压缩和性能优化。

注意:通过–model指定的参数项,会覆盖webpack.config.js 中的model选项。

5.3把JavaScript文件统一生成到js目录中

在 webpack.config.js 配置文件的 output节点中,进行如下的配置:

module.exports中

output: {
  path: path.join( __dirname, 'dist'),
  //明确告诉webpack把生成的 main.js 文件存放到 dist目录下的 js 子目录中
  filename: 'js/main.js',
}

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

module: { //所有第三方文件模块的匹配规则
  rules: [ //文件后缀名的匹配规则
    { 
      test: /\.jpg|png|gif$/,
      use: {
        //通过loader属性指定调用的loader
        loader: 'url-loader',
        //通过option属性指定参数
        options: {
          limit: 22229,
          outputPath: 'image'
        }
      }
    }
  ]

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

5.5自动清理dist目录下的旧文件

为了在每次打包发布时自动清理掉dist目录中的旧文件,可以安装并配置 clean-webpack-plugin 插件

5.5.1安装清理dist目录的 webpack插件

npm install clean-webpack-plugin -D

5.5.2配置

在 webpack.config.js 配置文件

module.exports中

const { CleanWebpackPlugin } = require( 'clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()
//把创建的 cleanPlugin 插件实例对象,挂载到plugins节点中
plugins: [htmlPlugin,cleanPlugin],  //挂载插件

6 Source Map

6.1 什么是Source Map

Source Map就是一个信息文件,里面储存着位置信息。也就是说,Source Map 文件中存储着压缩混淆后的代码所对应的转换前的位置。

有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。

Source Map 可以在报错时提示对应的源文件的行号,便于定位错误位置修改错误。

6.2 默认Source Map的问题

开发环境下默认生成的Source Map记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。示意图如下:

6.3 解决默认Source Map的问题

开发环境下,推荐在webpack.config.js中添加如下的配置,即可保证运行时报错的行数与源代码的行数保持一致:

module.exports = {
  mode: 'development',
  // eval-source-map 仅限在"开发模式"下使用,不建议在“生产模式"下使用。
  //此选项生成的Source Map 能够保证"运行时报错的行数"与"源代码的行数"保持一致
  devtool: 'eval-source-map' ,
  //省略其他配置项...
}

6.4 webpack生产环境下的Source Map

在生产环境下,如果省略了devtool选项,则最终生成的文件中不包含Source Map。这能够防止原始代码通过Source Map 的形式暴露给别有所图之人。

6.4.1只定位行数不暴露源码

在生产环境下,如果只想定位报错的具体行数,且不想暴露源码。此时可以将devtool的值设置为

nosources-source-map。实际效果如图所示:

在实际发布的时候,建议大家把 devtool 的值设置为nosources-source-map或直接关闭SourceMap。

6.4.2 定位行数且暴露源码

在生产环境下,如果想在定位报错行数的同时,展示具体报错的源码。此时可以将devtool的值设置为source-map。实际效果如图所示:

6.5 Source Map的最佳实践

开发环境下:

建议把devtool的值设置为eval-source-map

好处:可以精准定位到具体的错误行

生产环境下:

建议关闭Source Map 或将devtool的值设置为nosources-source-map

好处:防止源码泄露,提高网站的安全性

7 配置完成后的package.json与webpack.config.js

"scripts": {
    "dev": "webpack serve",
    "build": "webpack --mode production"
  },
// 使用Node.js中的导出语法,向外导出一个webpack的配置对象
module.exports = {
    // devtool: 'eval-source-map',
    devtool: 'nosources-source-map',
    // 代表webpack运行的模式,可选值有两个development和production
    mode: 'development',
    entry: path.join(__dirname, './src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'js/main.js'
    },
    // 插件的数组 将来webpack在运行时会加载并调用这些插件
    plugins: [htmlPlugin,new CleanWebpackPlugin()],
    devServer: {
        // 首次打包成功后自动打开浏览器
        open:true,
        // 在http协议中如果端口号为80可以省略
        port:80,
        // 指定主机运行的地址
        host:'127.0.0.1' 
    },
    module: {
        rules:[
            {test:/\.css$/, use:['style-loader', 'css-loader']},
            {test:/\.less$/, use:['style-loader', 'css-loader', 'less-loader']},
            // 处理图片文件的loader
            // 如果需要调用的loader只有一个,则只传递一个字符串就行,如果有多个loader则必须指定数组
            { test:/\.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images' },
            // 使用babel-loader处理高级的js语法
            // 注意:必须使用exclude排除指定项;因为node_modules目录下的第三方包不需要被打包
            {test:/\.js$/, use: 'babel-loader', exclude: /node_modules/}
        ]
    }
}

8 使用@代替./ …/

@代表src源代码目录

使用@从src开始向内查找

使用./ …/ 从当前文件向外查找

8.1 配置

webpack.config.js文件

const path = require('path')
//导入html-webpack-plugin插件 得到插件的构造函数
const HtmlPlugin = require('html-webpack-plugin')
// new构造函数创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
    // 指定要复制哪个页面
    template: './src/index.html',
    // 指定复制出来的文件名和存放路径
    filename: './index.html'
})
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// 使用Node.js中的导出语法,向外导出一个webpack的配置对象
module.exports = {
    // devtool: 'eval-source-map',
    devtool: 'nosources-source-map',
    // 代表webpack运行的模式,可选值有两个development和production
    mode: 'development',
    entry: path.join(__dirname, './src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'js/main.js'
    },
    // 插件的数组 将来webpack在运行时会加载并调用这些插件
    plugins: [htmlPlugin,new CleanWebpackPlugin()],
    devServer: {
        // 首次打包成功后自动打开浏览器
        open:true,
        // 在http协议中如果端口号为80可以省略
        port:8080,
        // 指定主机运行的地址
        host:'127.0.0.1' 
    },
    module: {
        rules:[
            {test:/\.css$/, use:['style-loader', 'css-loader']},
            {test:/\.less$/, use:['style-loader', 'css-loader', 'less-loader']},
            // 处理图片文件的loader
            // 如果需要调用的loader只有一个,则只传递一个字符串就行,如果有多个loader则必须指定数组
            { test:/\.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images' },
            // 使用babel-loader处理高级的js语法
            // 注意:必须使用exclude排除指定项;因为node_modules目录下的第三方包不需要被打包
            {test:/\.js$/, use: 'babel-loader', exclude: /node_modules/}
        ]
    },
    resolve: {
        alias: {
            //告诉webpack @代表src这一层目录
            '@' : path.join(__dirname, './src/')
        }
    }
}


相关文章
|
13天前
|
JSON 前端开发 JavaScript
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
该文章提供了Webpack的基础入门指南,涵盖安装配置、基本使用、加载器(Loaders)、插件(Plugins)的应用,以及如何通过Webpack优化前端项目的打包构建流程。
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
|
18天前
|
前端开发 JavaScript 开发者
工程化(webpack+vite)
工程化(webpack+vite)
|
1月前
|
前端开发 开发者
在前端开发中,webpack 作为一个强大的模块打包工具,为我们提供了丰富的功能和扩展性
【9月更文挑战第1天】在前端开发中,Webpack 作为强大的模块打包工具,提供了丰富的功能和扩展性。本文重点介绍 DefinePlugin 插件,详细探讨其原理、功能及实际应用。DefinePlugin 可在编译过程中动态定义全局变量,适用于环境变量配置、动态加载资源、接口地址配置等场景,有助于提升代码质量和开发效率。通过具体配置示例和注意事项,帮助开发者更好地利用此插件优化项目。
70 13
|
2月前
|
前端开发 JavaScript C++
【绝技大公开】Webpack VS Rollup:一场前端工程化领域的巅峰对决,谁能笑到最后?——揭秘两大构建神器背后的秘密与奇迹!
【8月更文挑战第12天】随着前端技术的发展,模块化与自动化构建成为标准实践。Webpack与Rollup作为主流构建工具,各具特色。Webpack是一款全能型打包器,能处理多种静态资源,配置灵活,适合复杂项目;Rollup专注于ES6模块打包,利用Tree Shaking技术减少冗余,生成更精简的代码。Rollup构建速度快,配置简洁,而Webpack则拥有更丰富的插件生态系统。选择合适的工具需根据项目需求和个人偏好决定。两者都能有效提升前端工程化水平,助力高质量应用开发。
28 1
|
2月前
|
JavaScript 前端开发 API
解锁前端开发新境界:Vue.js携手Webpack,打造高效构建流程,你的项目值得拥有!
【8月更文挑战第30天】随着前端技术的发展,模块化与组件化趋势愈发显著。Vue.js 以其简洁的 API 和灵活的组件系统,深受开发者喜爱;Webpack 则凭借强大的模块打包能力成为前端工程化的基石。两者结合,不仅简化了组件编写与引用,还通过模块热替换、代码分割等功能大幅提升开发效率。本文将通过具体示例,展示如何利用 Vue.js 和 Webpack 构建高效、有序的前端开发环境。从安装配置到实际应用,逐步解析这一组合的优势所在。
38 0
|
2月前
|
前端开发 开发者
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。本文阐述 DefinePlugin 的原理、用法及案例,包括安装配置、具体示例(如动态加载资源、配置接口地址)和注意事项,帮助开发者更好地利用此插件优化项目。
58 0
|
3月前
|
JSON 前端开发 JavaScript
前端工程化:Webpack配置全攻略
【7月更文挑战第14天】
55 6
|
3月前
|
JSON 缓存 前端开发
前端工程化:Webpack配置全攻略
【7月更文挑战第18天】
45 1
|
3月前
|
前端开发 JavaScript
webpack 和 babel 实用教程【前端必备】
webpack 和 babel 实用教程【前端必备】
30 0
|
26天前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架