【笔记】Webpack

Webpeack

1. 介绍

Webpack是一种前端资源构建工具,一个静态模块打包器(module bundler)

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

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

2. 五个核心概念

2.1 Entry

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

2.2 Output

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

2.3 Loader

Loader让Webpack能够去处理那些非js文件(webpack本身只理解js)

2.4 Plugins

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

2.5 Mode

模式(Mode)指示Webpack使用相应模式的配置

选项描述特点
development会将process.env.NODE_ENV的值设为development。 启用NamedChunksPlungs和N阿么的M哦读了书PLUgin。能让代码本地调试运行环境
production会将process.env.NODE_ENV的值设为 production。启用FaglgDependencyUsagePlugin,FalgIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,Occur人侧耳OrderPLUgin,SideEffectsFlagPlugin 和 UglifyJsPlugin。能让代码优化上线运行环境

打包指令

npm i webpack webpack-cli -D    // 安装webpack
// 开发环境

webpack ./src/index.js -o ./build/built.js --mode=development
// 生产环境


webpack ./src/index.js -o ./build/built.js --mode=production
  • 结论

webpack 只能打包 js/json 文件

生产环境和开发环境将es6 模块化编译成浏览器能识别的模块化

生产环境比开发环境多一个压缩js

3. webpack.config.js

webpage.config.js webpack 配置文件

作用: 指示webpack干哪些活 (当你运行webpack指令时,会加载里面的配置)

所有构建工具都是基于node平台运行的 模块化采用 common.js

// loder 下载 使用
// plugins 下载 引入 使用

const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.export = {
    // 入口起点
    entry:./src/index.js’,
    // 输出
    output:{
        // 输出文件名
        filename:'',
        // 输出路径
        // __dirname nodejs 的变量,代表当前文件的目录的绝对路径
        path:resolve(__dirname,'build')
    },
    // loder 的配置
    module:{
        rules:[
            // 详细的loder配置
            {
                // 匹配哪些文件
                test:/\.css$/,
                use:[    
                    // use执行顺序 自下到上 自右到左
                   // 创建style标签 将js中的样式资源添加到head中生效
                    'styele-loader',
                    // 将css文件编程commonjs模块加载js中,里面内容是样式字符串
                    'css-loader'
                ]
            },
            //    匹配less
            {
                test:'/\.less$/',
                use:[
                    'styele-loader',
                    'css-loader',
                     // 将less转换为css   注意需要下载 less 和 less-
                    'less-loder'
                 ]
             },
             //    匹配img
            {
                test:'/\.(jpg|png|gif)$/',
                loader:'url-loader',  // 只引入一个可以使用字符串
                options:{
                    // 图片大小 小于8kb 就会被base64处理
                    // 优点 减少请求数量(减轻服务器压力),缺点:文件体积会变大
                    limit:8*1024,
                    // 问题:url-loder 默认是es6模块化解析 而html-loader 
                    // 引入图片是commonjs 所以解析会出问题 
                    esModule:false,
                    // 给图片重命名 [hash:10] 去吐排尿前十位hash值  [ext]取图片原来拓展名
                }
                    name:'[hash:10].[ext]'
             },
              //    匹配 html的img图片
            {
                test:'/\.html$/',
                loader:'html-loader',  // 只引入一个可以使用字符串

            },
            // 打包其他资源(除了html/js/css 资源以外的资源)
            {
                // 排除css/js/html 资源
                exclude:/\.(css|js|html|less)$/,
                loader:'file-loader',
                options:{
                    name:'[hash:10].[ext]'
                }
            }
        ]
    },
    // 插件
    plugins:[
        // 详细配置
        new HtmlWebpackPlugin({
            // 复制 ./src/index.html 文件  并自动引入打包输出的所有资源(js、)
            template:'./src/index.html'
        })
    ],
    // 模式
    mode:'development' // 开发模式
    // mode:'production'  // 生产

    // dev-Server   // npm webpack-dev-server -D
    devServer:{
    contentBase:resolve(__dirname,'build'),
    // 启动gzip压缩
    compress:true,
    // 端口号
    port:3000,
    // 自动打开浏览器
    open:true
}
}

4. devServer

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

特点:只会在内存中编译打包,不会有任何输出

启动devServer指令为:npx webpack-dev-server

5. 提取css为单独文件

  • 引入插件 mini-css-extract-plugin

  • 使用插件

  • 使用插件的loader 替换 style-loader

    module:{
        rules:[
            {
                test:'/\.css$/',
                use:[
                    // 取代style-loader 作用:提取js中的css成单独文件
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new MiniCssExtractPlugin({
            // 对输出的css文件进行重命名
            filename:'css/built.css'
        })
    ]
    

6. css 兼容性处理

  • postcss —> psotcss-loader postcss-preset-env

  • 使用 loader 在loader配置plungins

    npm i psotcss-loader postcss-preset-env -D
    
    webpack.config
    // 设置node环境变量 为 开发环境
    process.env.NODE_ENV = 'development'
    
    module:{
        rules:[
            {
                test:'/\.css$/',
                use:[
                    // 取代style-loader 作用:提取js中的css成单独文件
                    MiniCssExtractPlugin.loader,
                    'css-loader',  // loader 的默认写法
                    // loader 的配置写法
                    {
                        loader:'postcss-loader',
                        options:{
                            ident:'postcss',
                            // 配置插件 作用:帮postcss找到package.josn中的
                            // browerslist里面的配置,通过配置加载指定的css兼容
                            plugins:()=>{
                                require('postcss-preset-env')()
                            }
                        }
                    }
    
                ]
            }
        ]
    },
    
    // package.json 文件
     ”browerslist“:{
     // 开发环境 --> 需要在webpack.config.js 中设置环境变量:
     //process.env.NODE_ENV = developement
     "development":[
     "last 1 chrome version" // 兼容最近的谷歌
     "last 1 firefox version" // 兼容最近的火狐
     "last 1 safari version" // 兼容最近的safari
     ],
     // 生产环境:默认是看生产环境(如果不配置node环境变量的话)
     "production":[
     // 兼容大部分浏览器 不兼容启用的 不兼容欧朋mini
     ">0.2%",
     "not dead",
     "not op_mini all"
     ]
     }
    
## 7. 压缩css文件

- optimize-css-asset-webpack-plugin 插件

```js
const OptimizeCssAssetsWebpackPlugin require('optimize-css-asset-webpack-plugin')


plugins:[
    new OptimizeCssAssetsWebpackPlugin()
]

8. eslint 语法检查

语法检查 依赖:eslint-loader eslint

    module:{
    rules:[
        {
            test:'/\.js$/',
            // 忽略
            exclude:/mode_modules/,
            loader:'eslint-loader',
            options:{
                // 自动修复eslint 的错误
                fix:true
            }
        }
    ]
},


// package.json 文件
"eslintConfig":{
     "extends":"airbub-base"       
 }
 // airbub ->>> eslint eslint-config-airbub-base eslint-plugin-import

js 兼容性处理

js兼容性处理:babel-loader @babel/core

1. 基本js兼容性处理 --》 @babel/preset-env

2.需要作兼容处理的就做:按需加载 --》 core-js (这两个结合使用)

module:{
    rules:[
        {
            test:'/\.js$/',
            // 忽略
            exclude:/mode_modules/,
            loader:'babel-loader',
            options:{
                // 预设
                presets:[
                    [
                        '@babel/prest-env',
                        {
                            //按需加载
                            useBuitIns:'usage',
                            // 指定core-js版本
                            corejs:{
                                version:3
                            },
                            targets:{
                                chrome:'60',
                                firefox:'60',
                                ie:'9',
                                safari:'10',
                                edge:'17'
                            }
                        }
                    ]
                ]
            }
        }
    ]
},

js 和 html 压缩

1. js文件在production 环境会自动压缩

2. html压缩

// 在HtmlWebpackPlungin 里添加minify配置


minify:{
    // 移除空格
    collapseWhitespace:true,
    // 移除注释
    removeComments:true
}

优化

生产环境优化

  • 优化打包构建速度

  • 优化代码运行的性能

开发环境优化

  • 优化打包速度

  • 优化代码调试

HMR

hot module replacement 热模块替换

作用:一个模块发生变化,只会重新打包这一个模块,极大提升构建速度

devServer:{
    contentBase:resolve(__dirname,'build'),
    // 启动gzip压缩
    compress:true,
    // 端口号
    port:3000,
    // 自动打开浏览器
    open:true,
    // 开启HMR  改了webpack 需要
    hot:true
}
  • 样式文件:可以使用HMR功能,因为style-loader内部实现了

  • js文件:默认不能使用HMR功能, 注意:HMR功能对js的处理,只能处理非入口js文件的其他文件

  • html文件:默认不能使用HMR功能,同时会出现问题:html文件不能热更新了

    解决:修改entry 入口 将html文件引入

    // 入口起点
        entry:['./src/index.js','./src/index.html'],
    

source-map

source-map : 一种 提供源代码到构建后代码映射技术 (如果构建后代码出错,通过映射可以追踪到代码错误)

module.export = {
    entry:'',
    ...
    devtool:'eval-source-map' // 开发环境推荐
    // devtool:'source-map'  // 生产环境推荐

}

oneOf

// 一下loader只会匹配一个   注意不能有两个配置处理同一个类型文件(oneOf提升构建速度)
module:{
    rules:[
        oneOf:[
            {},
            {},
            ...
        ]
    ]
}

缓存

  • babel 缓存

    cacheDirectory:true 让第二次打包速度更快

     {
                test:'/\.js$/',
                // 忽略
                exclude:/mode_modules/,
                loader:'babel-loader',
                options:{
                    ....
                }
                 // 第二次构建会读取之前缓存
                cacheDirectory:true
            }
    
  • 文件资源缓存

    hash:每次webpack构建都会生成一个唯一的hash值

    问题:因为js和css同时使用会有一个一样的hash值 如果重新打包,会导致所有缓存失效(可能没有改动所有资源)

    chunkhash:根据chunk生成的hash值,如果打包来源于一个chunk,那么hash值一样

    问题:css在js中被引入 属于一个hash

    contenhash:根据文件内容生产hash,不同文件值不一样

    作用: 让代码运行缓存更好使用

    // 用法
     filename:'css/built[contenthash:10].css'
    

tree shaking

  • 前提:1. 必须使用es6 模块化 2. 开启production

  • 作用: 减少代码体积 去除无用代码

在package.json 中配置

"sideEffects":false    // 所有代码都没有副作用 (都会进行tree shaking)
                        // 问题:可能会把 css / @babel/polyfill 文件干掉
"sideEffects":["*.css"]

code split

  1. 通过写单入口 和 多入口
多入口写法: entry:{    

                            index:'./js/index.js',

                            test:'./js/test.js'

                    }
  1. 配置optimization
  • 可以将node_modules中的代码单独打包到一个chunk最终输出

  • 自动分析多个入口chunk中,有没有公共的文件,如果有会打包成一个单独的chunk

optimiazation:{

   splitChunks:{

       chunks:'all'

}

}
  1. 通过js代码,让某个文件被单独打包成一个chunk

import动态导入语法:能将某个文件单独打包

PWA

Progressive Web Application,全称“渐进式网页应用”,是谷歌主导的一种新时代网页(应用)。

简单的理解,就是你的网页,可以通过某种方式达到离线使用。

  • eslint 不认识window,navigator全局变量

    解决:修改package.json 中 eslintConfig配置

    “env”:{

    “borwer”:true

    }

  • sw代码必须运行在服务器上

// 下载并引入 workbox-webpack-plugin
// 在plugins 中使用
new WorkboxWebpackPlugin.GenerateSw({
    // 帮住serviceworker快速启动  删除就得serviceworker
    // 生成一个serviceworker 配置 文件
    clientsClaim:true,
    skipWaiting:true
})


// 在入口文件注册serviceworker
// 注册一个serviceworker  处理兼容性问题 
if('serviceworker' in navigator) {
    window.addEventListener('load',()=>{
        navigator.serviceworker
            .register('/service-worker.js')
            .then(()=>{
                console.log('sw注册成功了')
            })
            .catch(()=>{
                console.log('sw注册失败了')
            })
    })
}

多进程打包

依赖 npm i thread-loader -D

  • 开启多进程打包 进程启动大概为600ms, 进程通讯也要有开销 只有工作消耗时间较长,才需要多进程
{
            test:'/\.css$/',
            use:[
                // 取代style-loader 作用:提取js中的css成单独文件
                MiniCssExtractPlugin.loader,
                'css-loader',  // loader 的默认写法
                {   // 写在需要多进程的loader 后面(因为loader自下而上)
                    loader:'thread-loader',
                    options:{
                        workers:2  // 进程
                    }
                },
                // loader 的配置写法
                {
                    loader:'postcss-loader',
                    options:{
                        ident:'postcss',
                        // 配置插件 作用:帮postcss找到package.josn中的
                        // browerslist里面的配置,通过配置加载指定的css兼容
                        plugins:()=>{
                            require('postcss-preset-env')()
                        }
                    }
                }

            ]
        }

externals

externals:{
    // 拒绝JQ被打包进来
    juqery:"jQuery"
}
// 同时CDN 引入

dll

plugins:[

    // 告诉webpack那些库不参与打包,同时使用时名称也得
    new webpack.DllReferencePlugin({
        manifest: resolve(__dirname,'dll/manifest.json')
    })
    // 将某个文件打包输出去,并在html中自动引入
    new AddAssetHtmlWebpackPlugin({
        filepath:resolve(__dirname,'dll/jquery.js')
    })
]
// 新建一个webpack.dll.js     
// 使用dll技术,对某些库(第三方)单独打包
// 当运行webpack时  默认去找webpack.config.js  所有要用 wenpack --config webpack.dell.js

const {resolve} = require('psth')
const webpack = require('webpack')

module.export = {
    entry:{
        // 最终生产[name] --》 jquery   ['jquery'] --> 要打包的库时juqery
        jquery:['jquery']
    },
    output:{
        filename:'[name],js'
        path:resolve(__dirname,'dll'),
        library:'[name]_[hash]'  // 打包库里面想外暴露的
    },
    plugins:[
        // 打包生成一个manifest.json --》 提供和jquery映射
        new webapck.DllPugin({
            name:'[name]_[hash]',
            path:resolve(__dirname,'dll/manifest.json')  // 输出文件路径
        })
    ],
    mode:'production'
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值