手记

【九月打卡】 第四天 webpack的学习笔记,如何使用webpack

webpack 是一个现代 JavaScript 应用程序的静态模块打包器,当 webpack 处理应用程序时,会递归构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成一个或多个 bundle

主要有四个核心概念:

  • 入口:起点指示webpack应该使用那个模块,来作为构建其内部依赖图的开始,默认是./src/index.js,可以配置entry属性来指定入口。

  • 输出:告诉webpack在哪里输出所创建的bundle,以及如何命名这些文件,输出默认值是./dist/main.js,可以通过output来指定出口。

  • loader:loader让webpack有能力去处理其他类型的文件,并将他们转化为有效模块,以供他们使用,以及被添加到依赖图中。

  • plugin:loader用于转换某些类型的模块,而插件则可以用于执行范围更广的任务,包括:打包优化,资源管理,注入环境变量。使用插件可以通过require导入,再添加到plugins数组中。

项目初始化

新建文档webpack5.0,运行npm init -y初始化项目,安装webpackwebapck-cli



npm install webpack webpack-cli -D

安装的版本为:

"webpack": "^5.64.2","webpack-cli": "^4.9.1"

新建一个src/idnex.js文件:

class Animal {    constructor(name) {        this.name = name;
    }    getName() {        return this.name;
    }
}const dog = new Animal('dog');

在命令行运行npx webpack --mode=development可以看到在根目录下新增了一个dist/main.js文件。这里使用的都是webapck的默认配置,在 node_modules/webpack/lib/WebpackOptionsDefaulter.js里详细看一下,在node_modules/webpack/lib/config/defaults.js

F(output, "path", () => path.join(process.cwd(), "dist"));


我们可以自己设置入口与出口配置,自定义打包的入口文件与出口文件:

新建webpack.config.js文件:

const path = require('path'); module.exports = {   entry:'./src/index.js',   output: {     path: path.resolve(__dirname, 'dist'), //必须是绝对路径     filename: 'bundle.js',   } }


一般我们在项目打包就是npm run build,现在需要在package.json的script中添加配置:

"build": "cross-env NODE_ENV=production webpack", "devBuild": "cross-env NODE_ENV=development webpack"


完整的webpack.config.js如下:

const path = require('path'); const isDev = process.env.NODE_ENV === 'development'; module.exports = {   mode:isDev ? 'development' : 'production',   devtool: isDev ? 'source-map' : false,   entry:'./src/index.js',   output: {     path: path.resolve(__dirname, 'dist'), //必须是绝对路径     filename: 'bundle.js',   } }


现在运行npm run build或者npm run devBuild即可完成打包,即在dist/build.js下生成了打包文件。

项目基础已经搭建完成,接下来做一些有意思的小案例。

基本案例

将js转译为低版本

前面打包的代码还是ES6的代码,要将ES6代码转译为ES5代码,需要使用babel-loader和其依赖。

npm install babel-loader -D npm install @babel/core @babel/preset-env @babel/plugin-transform-runtime -D npm install @babel/runtime @babel/runtime-corejs3


loader有两个属性:

  1. test 属性,识别出哪些文件会被转换。

  2. use 属性,定义出在进行转换时,应该使用哪个 loader。

loader使用有两种方式:

  • 配置方式(推荐):在webpack.config.js文件中指定loader

  • 内联方式:在每个import语句中显示指定loader

webpack.config.js添加module.rules:

rules: [ {         test: /\.jsx?$/,         use: ['babel-loader'],         exclude: /node_modules/ //排除 node_modules 目录      } ]


同时在根目录下配置一个.babelrc文件:

{     "presets": ["@babel/preset-env"],     "plugins": [         [             "@babel/plugin-transform-runtime",             {                 "corejs": 3             }         ]     ] }


在命令行运行npm run devBuild,就可以看到ES6代码已经被转译了。

在浏览器中查看页面

可以根据配置文件动态展示页面内容。

安装所需插件:

"webpack-dev-server": "^4.5.0" "html-webpack-plugin": "^5.5.0",


先在根目录下新建一个public/index.htmlpublic/config.js文件:

module.exports = {     dog: {         template: {             hair: 'red',             name:'jack'         }     },     cat: {         template: {             hair: 'black',             name:'Jerry'         }     } }


<!DOCTYPE html> <html> <head> <title><%= (htmlWebpackPlugin.options.config.name) %></title> <meta charset="utf-8"> </head> <body>     <div><%= (htmlWebpackPlugin.options.config.hair) %></div>     <div class="color">hello world</div>      </script> </body> </html>


package.json中的script添加:

"dev": "cross-env NODE_ENV=development webpack-dev-server" 复制代码


webpack.config.js添加插件:

const HtmlWebpackPlugin = require('html-webpack-plugin'); ... plugins: [     new HtmlWebpackPlugin({       template: './public/index.html',       filename: 'index.html', //打包后的文件名       config: config.template     })   ],


运行npm run dev,在http://localhost:8080/中即可看到dog模板中的内容。

处理样式文件

webpack处理css需要借助loader。首先安装依赖:

npm install style-loader less-loader css-loader postcss-loader autoprefixer less -D


在relus中添加:

{       test: /\.(le|c)ss$/,       use: ['style-loader', 'css-loader', {           loader: 'postcss-loader',           options: {               plugins: function () {                   return [                       require('autoprefixer')()                   ]               }           }         }, 'less-loader'],         exclude: /node_modules/     }


新建src/index.css

.color{     color:red; } 复制代码


这里改了半天,webpack5.0和高版本loader不兼容,降级之后打包成功。

"autoprefixer": "^9.0.0", "postcss-loader": "^3.0.0", //https://github.com/laravel-mix/laravel-mix/issues/2471 //https://stackoverflow.com/questions/64057023/error-postcss-plugin-autoprefixer-requires-postcss-8-update-postcss-or-downgra


已经可以看到页面的hello world变成了红色。

图片处理

处理本地资源可以使用url-loader

在rules配置loader:

{         test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,         use: [           {             loader: 'url-loader',             options: {                 limit: 10240, //10K                 esModule: false             }           }         ],         exclude: /node_modules/       }


index.css中引入图片:

.img{     width:100vh;     height: 100px;     border:1px solid red;     background:url('../pka1.png'); }


既可以成功在页面上看到所引入的图片了。

静态资源拷贝

当需要使用已有的本地文件但不需要webpack编译,除了手动复制到构建目录(dist),还可以是使用copy-webpack-plugin插件。

该插件有两个参数:

  • patterns, {Array<String|Object>} ,为插件指定文件相关模式。

    • from 复制文件的路径

    • to  输出路径

    • content  决定如何解释from的路径

    • toType  确定to的选项  dir-目录,file-文件,template-模板

    • globOptions, 允许配置插件使用的 glob 模式匹配库

  • options, {Object} , 指定插件选项

新建文件public/js/color.js``public/js/filter.js和:

console.log('这是待引入的js文件') 复制代码


console.log('这是要过滤的js文件') 复制代码


webpack.config.js中添加配置:

const CopyWebpackPlugin = require('copy-webpack-plugin'); ... //plugins中添加 new CopyWebpackPlugin({     patterns:[        {           from: 'public/js/*.js',           to: path.resolve(__dirname, 'dist', 'js'),           toType:'dir',           globOptions:{             ignore: ["**/filter.*"],           }         }, }) 复制代码


运行npm run devBuild,即可看见在dist目录下有一个拷贝的js文件夹,里面只有color.js

单独打包css文件

如果需要单独打包css文件,可以用到mini-css-extract-plugin插件。

这个插件将 CSS 提取到单独的文件中。它为每个包含 CSS 的 JS 文件创建一个 CSS 文件。它支持按需加载 CSS 和 SourceMap。

它建立在新的 webpack v5 功能之上,并且需要 webpack 5 才能工作。

常用参数:

  • filename 确定每个输出css文件的名称

  • chunkFilename  确定非条目块的名称

首先安装依赖:npm install mini-css-extract-plugin -D

更改webapck.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 。。。 new MiniCssExtractPlugin({     filename: 'css/[name].css' })


并且使用MiniCssExtractPlugin.loader替换style-loader

运行nom run devBuild,既可以看见dist目录下新增了一个css文件。

按需加载

很多时候我们不需要一次性加载所有的JS文件,而应该在不同阶段去加载所需要的代码。webpack内置了强大的分割代码的功能可以实现按需加载。

比如vue文档中提到可以使用路由懒加载提升性能:

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')


热更新

配置devServer中的hot:true,随后在webpack.config.js中配置:

const webpack = require('webpack'); ...//在plugins中添加插件 new webpack.HotModuleReplacementPlugin()




0人推荐
随时随地看视频
慕课网APP