• webpack学习


    webpack

    为什么需要webpack

    本质上,Webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 Webpack 处理应用程序时,它会递归地构建一个依赖关系图(Dependency Graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。

    在开发中一般会使用less,sass,vue等需要转化为浏览器可以识别的css,js,html,es6->es5
    压缩代码,兼容处理

    5个基本概念

    entry:入口文件

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

    output:出口文件

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

    Loader:处理css,img

    让webpack去处理非JavaScript资源的文件,比如css、img等,将他们可以处理成一个webpack可以识别的资源,可以理解成一个翻译的过程。(webpack自身只能理解json和js)

    plugins:插件

    插件可以用来执行更加广的任务,插件的范围包括打包优化和压缩

    mode:模式

    模式指示webpack使用相应模式的配置。
    开发模式(development):配置比较简单,能让代码本地调试运行的环境。
    生产模式(production):代码需要不断优化达到性能最好。能让代码优化上线运行的环境。
    都会自动启用一些插件,生产模式使用插件更多

    功能介绍

    开发模式:仅编译es6 development

    生产模式:编译+压缩 production

    创建+使用

    1.初始化

    npm init -y
    //生成package.json文件
    
    • 1
    • 2

    2.下载

    npm i webpack webpack-cli --save-dev
    
    • 1

    3.根目录创建webpack.config.js文件,注意文件夹的位置

    在这里插入图片描述

    //webpack.config.js
    
    const path = require('path') // 引用path模块
    module.exports = { 
    
        entry:"./src/index.js",    // 入口文件
     
        output:{   // 出口文件       
            path:path.resolve(__dirname,'build'),// 输出的路径  是绝对路径     
            filename:'build.js',  // 输出的文件名称
        },
        
        mode:"production"// 使用生产
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4.npx webpack

    插件:html-webpack-plugin

    html-webpack-plugin 是 webpack 中的 HTML 插件,可以通过此插件自定制 index.html 页面的内容。
    HTML 插件复制的 index.html 页面,到dist目录下,自动注入了打包的 bundle.js 文件

    在这里插入图片描述

    1.下载

      npm i --save-dev html-webpack-plugin
    
    • 1

    2.使用

    const path = require('path') // 引用path模块
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = { 
    
        entry:"./src/index.js",    // 入口文件
     
        output:{   // 出口文件       
            path:path.resolve(__dirname,'./dist'),// 输出的路径  是绝对路径     
            filename:'build.js',  // 输出的文件名称
            clean:true,//清除之前遗留的旧的文件
        },
        
        mode:"production",// 使用生产
        plugins:[
            new HtmlWebpackPlugin({
                template:'./index.html',//模板
                filename:'app.html',//输出文件名
                inject:'body'//打包生成的script所在html的位置,默认在head标签里面
        })]
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    devtool:‘inline-source-map’,在开发模式下正常显示build.js下的js代码

    //  webpack.config.js
    	mode:"development",// 使用开发
        devtool:'inline-source-map',//在开发模式下正常显示build.js下的js代码
    
    • 1
    • 2
    • 3

    development模式下编译的build.js
    在这里插入图片描述
    转化完
    在这里插入图片描述

    - -watch 实施检测代码变化

    在这里插入图片描述

    webpack-dev-server 提供一个基本的web server 并且具有live reloading(实时加载)

    1.安装

    npm install  webpack-dev-server -D
    
    • 1

    2.配置

    devServer:{
            static:'./dist',//devServer指向的路径
        },
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    原理

    不输出物理文件,把打包好的文件放到内存里,把dist文件夹删掉也可以

    资源模块 asset module 是一种模块类型,允许webpack打包其他类型的文件(字体,图片)

    (1)asset/resource:单独文件+URL

     module:{
            rules:[//配置不同对象去加载不同类型的文件
                {
                    test:/\.png$/,//通过正则表达式,判断加载文件的类型
                    type:'asset/resource',     
                    generator:{//定义文件的名字和路径
                        filename:'images/[contenthash][ext]'
                    }
                }
            ]
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    打包出来一个图片资源
    在这里插入图片描述

    //页面显示出来图片
    import imgsrc from '../assets/1.png'//imgsrc 是一个url地址
    const img=document.createElement('img')
    img.src=imgsrc
    document.body.appendChild(img)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (2)asset/inline : Data URL

    不导出新的图片 ,生成base64格式路径

     {
                    test:/\.jpg$/,//导入jpg文件
                    type:'asset/inline',
                }
    
    • 1
    • 2
    • 3
    • 4

    (3)asset/source:源代码

      {
                    test:/\.txt$/,//导入文本文件
                    type:'asset/source',
                },
    
    • 1
    • 2
    • 3
    • 4

    (4)asset:Data URL/单独文件自动选择

    默认大于8k就生成新文件

    {
                    test:/\.jpg$/,//导入jpg文件
                    type:'asset',
                    parser:{//设置最大值,大于这个值就生成文件
                    	dataUrlCondition:{
                    		maxSize:4*1024*1024//4兆,默认4*1024
                    	}
                    }
                },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    加载css文件

    import  './index.css';
    //不配置会报错
    
    • 1
    • 2

    在这里插入图片描述

    1.下载css-loader,style-loader

    npm install css-loader -D
    npm install style-loader -D//帮助我们把css布局到页面
    
    • 1
    • 2

    2.配置

    {
             test:/\.css$/,//加载css文件
             use:['style-loader','css-loader']//注意顺序
               }
    
    • 1
    • 2
    • 3
    • 4

    //在head标签里面加载出style
    在这里插入图片描述

    解析less文件

    1.下载

    npm install less-loader less -D
    
    • 1

    2.配置

    {
                test:/\.(css|less)$/,//加载css文件
                use:['style-loader','css-loader','less-loader']//注意顺序,从右往左解析
    
               }
    
    
    import  './style.less';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    抽离和压缩css

    1.下载

    npm install mini-css-extract-plugin  -D //抽离所以css文件组合成一个
    npm install css-minimizer-webpack-plugin -D//css文件压缩
    
    • 1
    • 2

    2.配置

    1.引入const MiniCssExtractPlugin=require('mini-css-extract-plugin')
    	const CssMinimizerPlugin=require('css-minimizer-webpack-plugin')
    2.plugins中实例化
    	plugins:[
        new MiniCssExtractPlugin({
    		 filename:'styles/[contenthash].css'//修改打包出来的文件地址,contenthash根据css内容生成哈希字符串
    	})
        ],
        
    3.删除style-loader,配置MiniCssExtractPlugin.loader
     module:{
            rules:[//配置不同对象去加载不同类型的文件
               {
                test:/\.(css|less)$/,//加载css文件
                use:[MiniCssExtractPlugin.loader,'css-loader','less-loader']//注意顺序,从右往左解析
               },
            ]
        },
    4.  修改 mode:"production",
    5.    optimization:{//和entry平级
            minimizer:[
                new CssMinimizerPlugin()
            ]
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    加载字体

    style.css
    @font-face {
        font-family: 'iconfont';
        src: url('../assets/iconfont.ttf') format('truetype');
    }
    .icon{
        font-family: 'iconfont';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
     {
                test:/\.(woff|woff2|eot|ttf|otf)$/,//加载字体
               }
    
    • 1
    • 2
    • 3

    加载数据xml,csv

    1.下载

    npm install csv-loader xml-loader -D
    
    • 1

    2.配置

    			{
                test:/\.(csv|tsv|$)/,
                use:'csv-loader'
               },
               {
                test:/\.xml$/,
                use:'xml-loader'
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    自定义json模块parser

    1.下载

     npm install toml yaml json5 -D
    
    • 1

    2.配置

    //导入
    const toml=require('toml')
    const yamo=require('yaml')
    const json5=require('json5')
    
    • 1
    • 2
    • 3
    • 4
    {
    	test:/\.toml$/,
    	type:'json',
    	parser:{//解析器
    		parse:toml.parse
    	}
    },
    {
    	test:/\.yaml$/,
    	type:'json',
    	parser:{//解析器
    		parse:yaml.parse
    	}
    },
    {
    	test:/\.json5$/,
    	type:'json',
    	parser:{//解析器
    		parse:json5.parse
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    babel-loader es6=>es5

    1.下载

    npm install babel-loader @babel/core @babel/preset-env
    npm install @babel/runtime -D
    npm install @babel/plugin-transform-runtime -D
    
    
    babel-loader :解析es6
    @babel/core:核心模块
    @babel/preset-env:预设,一组插件集合
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.配置

     {
                test:/\.js$/,
                exclude:/node_modules/,//排除node module里面的js代码
                use:{
                    loader:'babel-loader',               
                    options:{
                        presets:['@babel/preset-env'],
                        plugins:[
                            [
                               '@babel/plugin-transform-runtime' 
                            ]
                        ]
                    }
                }
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    regeneratorRuntime插件:是webpack打包生成的全局辅助函数,由babel生成,用于兼容async,await

    分离代码

    (1).修改入口节点entry

      entry:{// 入口文件
            index:{
                import:'./src/index.js',
                dependOn:'shared'//可以把共享的文件定义出啦
            },
            another:{
                import:'./src/another-module.js',
                dependOn:'shared'//可以把共享的文件定义出啦
            },
            shared:'lodash'//当两个模块都有lodash模块的时候,抽离出来,取名shared
        },    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (2).spliteChunks

     entry:{    // 入口文件
            index:'./src/index.js',
            another:'./src/another-module.js'
        },
     optimization:{
            splitChunks:{//代码分割,抽离公共的保存到一个文件
                chunks:'all'
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (3).动态导入import函数

    //懒加载
    button.addEnentListener('click',()=>{
    import(/*webpackChunkName:'math'*/'./1.js').then((res)=>{
    	res.add(2,3)
    })
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    //预加载webpackPrefetch:true
    button.addEnentListener('click',()=>{
    import(/*webpackChunkName:'math',webpackPrefetch:true*/'./1.js').then((res)=>{
    	res.add(2,3)
    })
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    缓存

    当文件内容发生改变,而文件名没有改变的时候,浏览器会使用缓存,
    所以要使用’[name].[contenthash].js’

     output:{   // 出口文件            
            filename:'[name].[contenthash].js',  // 输出的文件名称,contenthash根据文件内容生成哈希字符串,文件名随着文件内容变化而变化
           
        },
    
    • 1
    • 2
    • 3
    • 4

    缓存第三方库

     optimization:{
            minimizer:[
                new CssMinimizerPlugin()
            ],
            splitChunks:{//代码分割,抽离公共的保存到一个文件
                cacheGroups:{
                    vendor:{
                        test:/[\\/]node_modules[\\/]/,
                        name:'vendors',
                        chunks:'all'
                    }
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    拆分开发环境和生产环境配置

    公共路径

     output:{   // 出口文件       
            publicPath:'http://localhost:8080/'//设置公共路径
        },
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    环境变量

    消除开发和生产环境的差异
    npx webpack --env production

    //转成一个函数
    module.exports =(env)=> {
    //如果传入值了就用
     mode:env.production?'production':'development',// 模式
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    因为 minimizer:[new CssMinimizerPlugin() ],配置css压缩所以手动配置
    npm install terser-webpack-plugin -D //压缩js文件

    const TerserPlugin=require('terser-webpack-plugin')
    minimizer:[
                new CssMinimizerPlugin(),
                new TerserPlugin()
            ],
    
    • 1
    • 2
    • 3
    • 4
    • 5

    生成两个文件来分别配置

    webpack.config.dev.js
    webpack.config.prod.js
    npm webpack -c ./config/webpack.config.dev.js//指定文件

    npm脚本,自定义package.json

    //package.json
    {
        "scripts": {
            "start": "npx webpack serve -c ./config/webpack.config.dev.js",
            "build":"npx webpack  -c ./config/webpack.config.prod.js"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    npx run start

    source-map:构建后代码出错了,通过映射可以追踪源代码错误,让我们报错的代码和源代码做关联

    在这里插入图片描述
    最终得出最好的两种方案 --> source-map(最完整) / cheap-module-souce-map(错误提示一整行忽略列)

    devserver

    devServer: {
            contentBase: path.join(__dirname, 'dist'),
            compress: true,//压缩
            port: 9000,//端口号
            headers:{},//设置请求头
            proxy: {
                '/api': {
                    target: 'https://api.github.com'
                }
            }
            // ...
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    redis怎么设计一个高性能hash表
    Reactor 测试-响应式编程-007
    基于Git和Nginx搭建自己的私人图床,告别图片404
    git常用命令
    2021 华数杯全国大学生数学建模竞赛A题-电动汽车无线充电优化匹配研究(附带赛题解析&获奖论文及MATLAB代码)
    Windows网络与通信程序设计实验四:基于WSAEventSelect模型的通信仿真
    Vue路由跳转至页面后多次渲染
    t-product的matlab实现
    【redis】SpringBoot整合+geo地理位置应用
    Vue项目文件导入、导出
  • 原文地址:https://blog.csdn.net/weixin_51109349/article/details/126162723