webpack打包

webpack是什么:

webpack是一种前端资源构建工具,一个静态模块打包器

在webpack看来,前端的所有资源文件(js/json/img/less…)都会作为模块处理

它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源

webpack五个核心概念:

1.Entry

入口(Entry)指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l2Uf59vE-1617326248838)(D:\webpack笔记\1.PNG)]

2.output

输出指示webpack打包之后的资源bundles输出到哪里去,以及如何命名

3.Loader

Loader让webpack能够去处理那些非JavaScript文件,css/img文件webpack看不清,loader负责去处理这些文件

4.Plugins

插件(Plugins)可以用于执行范围更广的任务,插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等等

5.Mode

(1)development----------开发模式:能让代码在本地进行调试,配置简单

启动插件:NamedChunkPlugin和NamedModulesPlugin

(2)production----------生产模式:能让代码优化上线运行的环境,要考虑各种优化措施还有兼容,配置复杂

启动插件:FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和UglifyJsPlugin

webpack基本安装过程:

(1)npm init----------全局初始化

(2)一直按enter键

(3)全局安装:

npm i webpack webpack-cli -g

(4)本地安装

npm i webpack webpack-cli -D

打包样式资源:

各个插件的版本控制:

{
  "name": "webpack_test",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.13.10",
    "@babel/polyfill": "^7.12.1",
    "@babel/preset-env": "^7.13.10",
    "babel-loader": "^8.2.2",
    "core.js": "^0.4.2",
    "css-loader": "^5.1.2",
    "eslint": "^7.22.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-import": "^2.22.1",
    "file-loader": "^6.2.0",
    "html-loader": "^2.1.2",
    "html-webpack-plugin": "^5.3.1",
    "less": "^4.1.1",
    "less-loader": "^8.0.0",
    "mini-css-extract-plugin": "^1.3.9",
    "optimize-css-assets-webpack-plugin": "^5.0.4",
    "postcss-loader": "^5.2.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^2.0.0",
    "url-loader": "^4.1.1",
    "webpack": "^5.19.0",
    "webpack-cli": "^4.5.0"
  },
  "devDependencies": {
    "@webpack-cli/serve": "^1.3.0",
    "webpack-dev-server": "^3.11.2"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base"
  },
  "sideEffects":["*.css"]
}

一定要注意webpack.config.js文件所放置的位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-astiwT8Y-1617326304394)(D:\webpack笔记\捕获.PNG)]

需要安装的包:css-loader,

1.在src目录下创建名称为webpack.config.js的文件名称

3.安装下载webpack,webpack-cli

演示的文件夹之前执行过一次npm i webpack webpack-cli -g

npm i webpack webpack-cli -D

6.如何查看效果

在打包好的build文件夹下新建一个inxex.html文件,然后右键浏览器打开文件就可以了

7.打包less、css文件

npm i css-loader style-loader less-loader -D

在index.js文件

import 'style-loader!css-loader!less-loader!./index.less'

如果上述写法报错的话,按照下述写法

import './index.less'

打包html资源:

npm i html-webpack-plugin -D

打包图片资源(背景图片

npm i url-loader  file-loader

打包HTML中的图片资源

npm i html-loader

打包其他资源(字体图标)不需要做优化,不需要压缩的资源

通过file-loader处理

开发服务器derServer:用来实现自动化(自动编译,自动打开浏览器,自动刷新浏览器)

下载包

npm i webpack-dev-server

热更新启动命令:

npx webpack serve

打包命令

npx webpack

代码示例:

// 这个文件是webpack的配置文件
// 作用:指示webpack干活,干那些活(当你运行webpack指令的时候,会加载其中的配置
// module.exports暴露一个对象
// resolve用来拼接绝对路径方法
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { Template } = require('webpack')
var webpack = require('webpack')
module.exports = {
    // webpack配置
    // 入口起点,指示webpack以哪个文件为起点
    entry:'./src/index.js',
    // 输出:打包好之后输出到哪里
    output:{
        // 输出文件名
        filename:'built.js',
        // 输出的路径
        // __dirname是node.js的一个变量代表当前文件的目录的绝对路径
        // webpack.config.js的绝对路径是03.打包样式资源,下述代码的意思就是03.打包样式资源文件夹下面的build文件夹
        // 目的是防止各系统的文件符号不出问题
        path:resolve(__dirname,'build')
    },
    // module里边写的就是loader的配置
    module:{
        rules:[
            // loader的详细配置
            {   
                // test是正则表达式,用来进行匹配哪些文件
                // 一旦检测到css文件,通过use里边规定好的插件去处理
                test:/\.css$/,
                use:[
                    // 执行顺序:先执行'css-loader',再执行'style-loader'
                    // 创建style标签,将js中的样式资源插入进行,添加到head中生效
                    'style-loader',
                    // 将css文件以字符串的形式变成一个commonjs模块,加载到js中,里面内容是样式字符串
                    'css-loader'
                ]
            },
            {   
                test:/\.less$/,
                use:[
                    'style-loader',
                    'css-loader',
                    // 将less文件编译成css文件
                    'less-loader'
                ]
            },
            {
                test:/\.(jpg|png|gif)$/,
                loader:'url-loader',
                options:{
                    limit:8*1024
                }
            },
            {
                test:/\.html$/,
                loader:'html-loader',
                options:{
                    esModule:false
                }
            },
            {
                exclude:/\.(css|js|less|html)$/,
                loader:'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 作用就是复制'./src/index.html'文件,并自动引入打包输出的所有资源
            template:'./src/index.html'
        }),
        new webpack.LoaderOptionsPlugin({
          // test: /\.xxx$/, // may apply this only for some modules
          options: {
            derServer: {
                contentBase:resolve(__dirname,'build'),
                //启动代码压缩
                conpress:true,
                //端口号是3000
                port:3000,
                //自动打开浏览器
                open:true
            }
          }
        })
    ],

    // 模式
    mode:'development'
}

生产环境的配置:

(1)提取css成单独文件:src目录下的所有css文件都会被打包到main.css中,减少打包js文件的体积,以link标签的方式插入html文件中,防止闪屏

npm i mini-css-extract-plugin

要将webpack.config.js中的style-loader给注释掉

(2)css兼容处理–使用库postcss,依赖postcss-loader,postcss-preset-env(帮助识别环境,能够让浏览器兼容到每个版本)

npm i postcss-loader postcss-preset-env

在package.json中要加上以下代码

意思是开发环境该怎么兼容,生产环境该怎么兼容:postcss如果你不指明的话,它认的就是生产环境,想要在开发环境中使用,需要在webpack.config.js中加上代码process.env.NODE_ENV = ‘development’

"browserslist": {
    "development":[
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production":[
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
 }

(3)压缩css:请求速度快,加载速度快,代码上线之前一定要压缩

npm i optimize-css-assets-webpack-plugin

(4)js语法检查eslint,只检查用户自己写的代码,第三方库不检查

设置检查规则,在package.json中eslintConfig中设置

"eslintConfig": {
    "extends": "airbnb-base"
  }

安装包:

npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import

(5)js兼容性处理:babel-loader

1.这三个包只能解决一些基本的兼容问题

npm i babel-loader @babel/preset-env @babel/core

2.全部js兼容处理:这个库将js所有有关兼容性的问题全部纳入了进来

问题:我只要解决部分兼容性问题,但是将所有兼容的代码都给引进来了

npm i @babel/polyfill

还需要在index.js中引入

import '@babel/polyfill'

3.按需加载----core.js,与方法2是冲突的,将方法2中index.js中的代码给注释掉

npm i core.js

(6)压缩js:生产环境下会自动压缩js

(7)压缩html:在new HtmlWebpackPlugin插件里边加上两句代码即可

具体代码

// 这个文件是webpack的配置文件
// 作用:指示webpack干活,干那些活(当你运行webpack指令的时候,会加载其中的配置
// module.exports暴露一个对象
// resolve用来拼接绝对路径方法
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { Template } = require('webpack')
const  MiniCssExtractPlugin = require('mini-css-extract-plugin')
var webpack = require('webpack')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
process.env.NODE_ENV = 'development'
module.exports = {
    // webpack配置
    // 入口起点,指示webpack以哪个文件为起点
    entry:['./src/index.js','./src/index.html'],
    // 输出:打包好之后输出到哪里
    output:{
        // 输出文件名
        filename:'built.[chunkhash:10].js',
        // 输出的路径
        // __dirname是node.js的一个变量代表当前文件的目录的绝对路径
        // webpack.config.js的绝对路径是03.打包样式资源,下述代码的意思就是03.打包样式资源文件夹下面的build文件夹
        // 目的是防止各系统的文件符号不出问题
        path:resolve(__dirname,'build')
    },
    // module里边写的就是loader的配置
    module:{
        rules:[
            // loader的详细配置
            {   
                // test是正则表达式,用来进行匹配哪些文件
                // 一旦检测到css文件,通过use里边规定好的插件去处理
                test:/\.css$/,
                use:[
                    // 执行顺序:先执行'css-loader',再执行'style-loader'
                    // 创建style标签,将js中的样式资源插入进行,添加到head中生效
                    // 'style-loader',
                    MiniCssExtractPlugin.loader,
                    // 将css文件以字符串的形式变成一个commonjs模块,加载到js中,里面内容是样式字符串
                    'css-loader',
                    // "browserslist": {
                    //     "development":[
                    //       "last 1 chrome version",
                    //       "last 1 firefox version",
                    //       "last 1 safari version"
                    //     ],
                    //     "production":[
                    //       ">0.2%",
                    //       "not dead",
                    //       "not op_mini all"
                    //     ]
                    // },
                    {
                        loader:'postcss-loader',
                        ident:'postcss',
                        options:{
                            postcssOptions:{
                                plugins:[
                                    require('postcss-preset-env')()
                                ]
                            }
                            
                        }
                    }
                ]
            },
            {   
                test:/\.less$/,
                use:[
                    // 创建style标签,将样式放进去
                    // 'style-loader',
                    MiniCssExtractPlugin.loader,
                    // 将css文件整合到js文件
                    'css-loader',
                    // 将less文件编译成css文件
                    'less-loader',
                    {
                        loader:'postcss-loader',
                        options:{
                            ident:'postcss',
                            postcssOptions:{
                                plugins:[
                                    require('postcss-preset-env')()
                                ]
                            }
                            
                        }
                    }
                ]
            },
            {
                test:/\.(jpg|png|gif)$/,
                loader:'url-loader',
                options:{
                    limit:8*1024
                }
            },
            {
                test:/\.html$/,
                loader:'html-loader',
                options:{
                    esModule:false
                }
            },
            {
                exclude:/\.(css|js|less|html)$/,
                loader:'file-loader'
            },
            {
                // 设置检查规则,在package.json中eslintConfig中设置
                test:/\.js$/,
                // 不检查第三方库
                exclude:/node_modules/,
                loader:'eslint-loader',
                options:{
                    // 帮我们自动修改错误
                    fix:true
                }
            },
            {   
                test:/\.js/,
                exclude:/node_modules/,
                loader:'babel-loader',
                options:{
                    // 指示babel做怎样的兼容处理
                    // 非常基本的兼容处理
                    presets:[
                        [
                            '@babel/preset-env',
                            {
                                useBuiltIns:'usage',
                                corejs:{
                                    version:3
                                },
                                // 通过targets制定兼容做到哪个版本
                                targets:{
                                    chrome:'60',
                                    firefox:'60',
                                    ie:'9',
                                    safari:'10',
                                    edge:'17'
                                }
                                    
                            }
                        ]
                    ],
                    cacheDirectory:true
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 作用就是复制'./src/index.html'文件,并自动引入打包输出的所有资源
            template:'./src/index.html',
            minify:{
                // 移除空格
                collapseWhitespace:true,
                // 移除注释
                removeComments:true
            }
        }),
        new webpack.LoaderOptionsPlugin({
          // test: /\.xxx$/, // may apply this only for some modules
          options: {
            derServer: {
                contentBase:resolve(__dirname,'build'),
                conpress:true,
                port:3000,
                // 开启HMR
                hot:true
            }
          }
        }),
        new MiniCssExtractPlugin({
            filename:'css/built.[chunkhash:10].css'
        }),
        new OptimizeCssAssetsWebpackPlugin()
    ],
    // plugins数组里边写上详细的插件配置
    // plugins:[
    //     // 插件功能认会创建一个空的html文件自动引入打包输出所有的资源(JS/CSS)
    //     // 问题:需要有结构的html文件
    //     new HtmlWebpackPlugin({
    //         // 作用就是复制'./src/index.html'文件,并自动引入打包输出的所有资源
    //         template:'./src/index.html'
    //     })
    // ],

    // 模式
    mode:'development',
    // derServer:{
    //     contentBase:resolve(__dirname,'build'),
    //     conpress:true,
    //     port:3000
    // }
    devtool:'inline-source-map'
}

webpack性能优化介绍:

1.开发环境性能优化

实际问题,你的代码发生一点点的变化,捎带着把那些没有变化的代码都进行打包了

(1)优化打包建构速度

生产环境是不需要HMR的,HMR是针对的开发环境

HMR功能:hot module replacement热模块替换。作用:一个模块发生变化,只会打包这一个模块(而不是打包所有模块)

derServer中新增一个属性

以下是用来处理css热更新:

hot:true

以下是用来处理html热更新:

entry:['./src/index.js','./src/index.html'],

(2)针对开发环境:优化代码调试----------source-map:提供一种源代码到构建代码的映射技术(如果构建代码出错了,通过映射关系追踪源代码错误,在webpack.config.js中添加以下代码

devtool:'source-map'

属性

【1】inline-source-map:内联,和打包js文件放在一块

错误代码准确信息和源代码错误位置

【2】hidden-source-map:外部

错误代码错误原因,但是没有错误位置

不能追踪源代码错误,只能提示到构建后代码错误的位置

【3】eval-source-map:内部

错误代码准确信息和源代码错误位置

【4】cheap-source-map:外部

错误代码准确信息和源代码错误位置,只能精确到行

【5】nosources-source-map:外部

错误代码准确信息,但是没有任何源代码信息

【6】cheap-module-source-map:外部

错误代码准确信息和源代码错误位置

【7】source-map:外部

错误代码准确信息和源代码错误位置

(推荐使用eval-cheap-souce-map)

2.生产环境性能优化

(1)优化打包建构速度

(2)优化代码的运行性能性能太差,用户体验度不好

缓存

1.babel缓存:直接配置就好了

cacheDirectory:true

{   
                test:/\.js/,
                exclude:/node_modules/,
                loader:'babel-loader',
                options:{
                    // 指示babel做怎样的兼容处理
                    // 非常基本的兼容处理
                    presets:[
                        [
                            '@babel/preset-env',
                            {
                                useBuiltIns:'usage',
                                corejs:{
                                    version:3
                                },
                                // 通过targets制定兼容做到哪个版本
                                targets:{
                                    chrome:'60',
                                    firefox:'60',
                                    ie:'9',
                                    safari:'10',
                                    edge:'17'
                                }
                                    
                            }
                        ]
                    ],
                    cacheDirectory:true
                }
            }

2.文件资源缓存

给打包的css和js文件添加chunkhash值

hash:

chunkhash:

contenthash:根据文件内容生成hash值,不同文件hash值一定不一样

tree shaking:忽略代码中没有被使用的代码,让代码的体积更小

使用的前提条件:

1.必须使用ES6模块化

2.开启production环境

在package.json配置,标记哪些问价不需要被tree shaking

"sideEffects":["*.css"]

code split:代码分割,非常重要的,主要研究的是js代码,在生产环境production中使用

比如你有两个js文件,webpack认会将文件打包成一个js文件,针对的是多入口

方式1:以下代码的作用:放在plugins之后

1.对于单页面应用,可以将node_modules中代码单独打包一个chunk最终输出

  1. 对于多页面应用,自动分析多入口chunk中,有没有公共的文件,如果有,会打包单独一个chunk
optimization:{
        splitChunks:{
            chunks:'all'
        }
    }

懒加载:针对的是js,不是图片的懒加载(跳过)

PWA:渐进式网络开发应用程序,因为兼容性问题,一般 大厂在使用,即使没有网络,也可以访问网站(跳过)

多进程打包:优化打包速度,和babel-loader放在一块

缺点:这个多进程打包启动时间需要600ms

npm i thread-loader
{   
                test:/\.js/,
                exclude:/node_modules/,
                use:[
                    'thread-loader',
                    {
                        loader:'babel-loader',
                options:{
                    // 指示babel做怎样的兼容处理
                    // 非常基本的兼容处理
                    presets:[
                        [
                            '@babel/preset-env',
                            {
                                useBuiltIns:'usage',
                                corejs:{
                                    version:3
                                },
                                // 通过targets制定兼容做到哪个版本
                                targets:{
                                    chrome:'60',
                                    firefox:'60',
                                    ie:'9',
                                    safari:'10',
                                    edge:'17'
                                }
                                    
                            }
                        ]
                    ],
                    cacheDirectory:true
                }
                    }
                ],
                
            }

externals:防止将某些包作用输出到我们的bundle中,比如 在使用jquery的CDN链接,这个时候可以通过externals将其禁止打包

比如你想使用jquery,用的cdn链接,放在了index.html中,可以这样配置:

externals;{
//库名----npm的包名
	jquery:'jQuery'
}

相关文章

Css3如何实现鼠标移上变长特效?(图文+视频)
css3怎么实现鼠标悬停图片时缓慢变大效果?(图文+视频)
jquery如何实现点击网页回到顶部效果?(图文+视频)
css3边框阴影效果怎么做?(图文+视频)
css怎么实现圆角边框和圆形效果?(图文+视频教程)
Css3如何实现旋转移动动画特效