webpack学习

1、安装

安装:npm install webpack webpack-cli -D

npx webpack -v查看版本  利用npx执行 本地文件夹里的webpack

npx webpack 进行打包

npx webpack --watch将文件进行监听,不用每次都重新输入npx webpack编译,但是需要手工刷新浏览器.

2、使用

2.1webpack.config.js中进行自定义配置

2.2HtmlWebpackPlugin使用

简化了 HTML 文件的创建,生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle

2.3 webpack-dev-server使用

npm install webpack-dev-server -D

监听文件变化、重新编译、自动实现浏览器刷新

2.4 loader

webpack自带只能解析js和JSON这种文件,loader可以让webpack去解析其他类型的文件

css-loader 负责加载css文件

style-loader 负责将css文件放到页面上

 npm install mini-css-extract-plugin 抽离和压缩css  基于webpack5

2.5拆分config

由于环境的切换,在config中使用环境变量会很乱,所以将config拆分为两个单独的config

2.6配置npm

每次编译都需要输入很长的命令,所以我们将父目录的package node_modules

package-lock,拷贝到当前目录下,然后配置npm

2.7提取公共配置,并进行合并

npm install webpack-merage -D

合并文件后,此时文件夹中没有dist文件夹,我先执行npm run start ,报错Content not from webpack is served from ,然后通过localhost访问页面报cannot get /,目录中也没有dist文件夹

原因:

run start 走的的dev-server.js
会启动webpack-dev-server,相应的代码会读进内存,不会在当前目录下产生dist文件夹,此时需要先执行npm run build 打包,dist文件夹就会出来,然后在run start访问页面

2.8webpack基础总结

webpack配置文件夹

webpack.config.common.js

// 抽离公共配置 保留通用代码
const path=require('path')//引入path模块
const HtmlWebpackPlugin = require('html-webpack-plugin');//引入插件 简化了 HTML 文件的创建
const MiniCssExtractPlugin = require('mini-css-extract-plugin');//引入插件 抽离css
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');//引入插件 压缩css 优化配置中注册
const TerserWebpackPlugin = require('terser-webpack-plugin')//压缩 生产环境JavaScript
// 自定义模块  npm install toml yaml json5 -D
const toml=require('toml')
const yaml=require('yaml')
const json5=require('json5')
// 然后将mode的环境切换为production
// 将module.exports ={}改写为module.exports =()=>{return {object}}函数,用来配置--env环境变量
//由于用代码区分环境配置比较不直观,所以采用拆分环境文件进行配置
//恢复为扁平对象,拆分环境配置
module.exports ={
  // npx webpack --env production --env goal=loca 编译时传递参数
//   console.log(env.goal);
 
   // entry: './src/index.js',//入口
  //分离代码 方法一 配置多个入口 ,但是会有代码重复问题
  // entry:{
  //   index:'./src/index.js',
  //   another:'./src/another-module.js'
  // },
  // 方法二、分离代码,防止重复
  // entry:{
  //   index:{
  //     import:'./src/index.js',
  //     dependOn:'shared',//可以把共享的文件抽离出来
  //   },
  //   another:{
  //     import:'./src/another-module.js',
  //     dependOn:'shared',//可以把共享的文件抽离出来
  //   },
  //   shared:'lodash',//抽离lodash命名为shared
  // },
  // 方法三 配置splitChunks  代码分割
  entry:{
    index:'./src/index.js',
    another:'./src/another-module.js'
  },
  // 方法4,动态导入:在单独js文件中导入模块,然后引用该js
  output: {   //出口
    // filename: 'bundle.js',       
    // filename:'[name].bundle.js',  //配合多入口命名
    //缓存,我们打包好的文件部署在服务器之后,浏览器第一次访问会缓存打包好的模块
    //如果我们修改了代码,文件名没有变,浏览器会使用本地缓存内容,因此通过修改输出文件名来解决这个问题,
    // 使用可替换模版字符串,缓存第三方库在cacheGroups中配置,节省网络流量,提升速度
    // filename:'[name].[contenthash].js',//缓存自己每次更新代码
    // filename:'script/[name].[contenthash].js',//将所有js文件放到一个文件夹
    path: path.resolve(__dirname,'../dist'),//__dirname基于当前文件路径,找到./dist的绝对路径,更改为两个. 
    // 上层目录
    clean:true, //清理上次打包的文件
    // assetModuleFilename:'images/test.png'//资源文件及文件名
    assetModuleFilename:'images/[contenthash][ext]',//根据文件内容生成文件名字,使用原文件扩展名
    // publicPath:'http://localhost:8080/'//配置公共路径 开发环境不需要
  },
  //实例化插件
  plugins: [
    new HtmlWebpackPlugin({
      template:'./index.html',//将自动生成的html文件按照index.html模版进行生成
      filename:'app.html' ,//更改文件名字
      inject:'body'//将script放入body中
  }),
  new MiniCssExtractPlugin({
    filename:'styles/[contenthash].css' ,//更改文件路径及名字
  }),
  
],
// devtool:'inline-source-map',//精准定位代码行数 //生产不需要
  // mode:'development',//配置编译模式
//   mode:env.production?'production':'development',//根据传入参数判断环境

//   devServer:{ //webpack-dev-server支持代码热更新,能迅速将更改后的代码更新到浏览器中。在这个模式下
//     // 构建后的代码在内存中,不会写入硬盘,所以读写速度快了很多。
//     static:'./dist'//指向的物理路径
//   },
  module:{//资源模块
    rules:[
      {
        test:/\.png$/,//以png作为扩展名
        type:'asset/resource',//资源模块类型: 发送一个单独的文件并导出 URL 打包后文件中显示
        generator:{//generator优先级高于assetModuleFilename
          filename:'images/[contenthash][ext]',
        }
      },
      {
        test:/\.svg$/,//以svg作为扩展名
        type:'asset/inline',//资源模块类型: 导出一个资源的 data URI 打包后文件中不显示
      
      },
      {
        test:/\.txt$/,//以txt作为扩展名
        type:'asset/source',//资源模块类型: 导出资源的源代码 打包后文件中不显示
      
      },
      {
        test:/\.jpg$/,//以jpg作为扩展名
        type:'asset',//资源模块类型: asset/resource 与 asset/inline之间自动选择 小于8k为inline
        parser:{//自己设置临界值
          dataUrlCondition:{
            maxSize: 4 * 1024 * 1024
          }
        }
      
      },
      {

        test:/\.(css|less)$/,//两种扩展名
        // use:'css-loader'
        // use:['style-loader','css-loader','less-loader']//注意顺序,从后往前加载,css-loader结果传递给style-loader,
        // less-loader解析css文件,然后传递给css-loader
        // 抽离css文件,替换style-loader在页面注入css,改用MiniCssExtractPlugin.loader
        use:[MiniCssExtractPlugin.loader,'css-loader','less-loader']
      },
      {
        //加载解析字体
        test:/\.(woff|woff2|eot|ttf|otf)$/,//字体文件格式很多
        type:'asset/resource'
      },
      // 以下两种加载数据文件
      {
        test:/\.(csv|tsv)$/,
        use:'csv-loader'
        //将文件转化为一个数组
      },
      {
        test:/\.xml$/,
        use:'xml-loader'
         //将文件转化为一个对象
      },
      // 自定义parser模块
      {
        test:/\.toml$/,
        type:'json',
        parser:{
          parse:toml.parse
        }
      },
      {
        test:/\.yaml$/,
        type:'json',
        parser:{
          parse:yaml.parse
        }
      },
      {
        test:/\.json5$/,
        type:'json',
        parser:{
          parse:json5.parse
        }
      },
      // babel-loader使用,可以将es6代码转换es5也支持代码
      // babel-loader @babel/core @babel/preset-env 
      // @babel/runtime regeneratorRuntime运行时候需要的内容
      //@babel/plugin-transform-runtime  自动处理regeneratorRuntime
      {
        test:/\.js$/,
        exclude:/node_modules/,//排除node_modules里面js
        use:{
          loader:'babel-loader',
          options:{
            presets:['@babel/preset-env'],//使用babel插件
            plugins:[
              [
                '@babel/plugin-transform-runtime'//使用插件
              ]
            ]
          },
         
        }
      },

    ]

  },
  //优化配置
  optimization:{
    // 开发环境不压缩
    // minimizer:[
    //   new CssMinimizerWebpackPlugin(),
    //   new TerserWebpackPlugin()
    // ]
    splitChunks:{
      // chunks:'all',//代码分割 与动态导入一起使用时也要打开
      cacheGroups:{//缓存第三方插件到浏览器
        vendor:{
          test:/[\\/]node_modules[\\/]/,
          name:'vendors',
          chunks:'all'
        }
      }
    }
  
 }

};

prod与dev

合并后的webpack.config.js

3、webpack高级

3.1 source-map  (webpack内置)

  devtool:'eval',
//   devtool:'source-map',
//   devtool:'hidden-source-map',
//   devtool:'inline-source-map',
//   devtool:'eval-source-map',
//   devtool:'cheap-source-map',
//开发环境一般不配置,因为有暴露源码风险,而且体积较大
  devtool:'cheap-module-source-map',//推荐使用

3.2devServer

模拟一个用户从浏览器中访问我们的web服务,读取我们的打包产物,观测代码在客户端的表现。

3.4githooks-husky

下载git后 git init 报错 git : 无法将“git”项识别为 cmdlet、函数、脚本文件或可运行程序的名称

配置环境变量解决

3.5依赖图

 npm i webpack-bundle-analyzer -D

const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');

new BundleAnalyzerPlugin()

3.6psstcss与css模块

3.7webpack5通用提升构建性能

通用环境提升构建性能

1.升级工具最新版

2.将loader用于最少数量的必要模块

3.每个loader和pligin都有启动时间,尽量少用

4.解析

5,减小编译结果的体积

6 dll 拆分 bundles,同时还大幅度提升了构建的速度

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
const WorkboxPlugin=require('workbox-webpack-plugin')
const webpack=require('webpack')
module.exports = {
  mode:'production',
  entry: './app.js',
  output:{
    clean:true,
    // publicPath:'/' ,
    path: path.resolve(__dirname, 'dist'),
    filename: 'mylib.js', //如果代码没用使用,在生产环境会被tree-shaking,所以配置library
    library: {
      name:'mylib',//暴露从入口起点导出的内容,避免tree-shaking
      type:'umd',
      globalObject:'globalThis'//全局对象来挂载 library。

    },
  },
 resolve:{
  alias:{
    '@':path.resolve(__dirname,'./src')//创建 import 或 require 的别名,来确保模块引入变得更简单
  },
  extensions:['.json','.js','.vue']//如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
 },
 externalsType:'script',//指定 externals 的默认类型
 externals:{//防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖。
  jquery: [//与import的from后面同步
    'https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js',
    'jQuery'
  ],

  // 例如,从 CDN 引入 jQuery,而不是把它打包
 },
  devServer: {
    static:path.resolve(__dirname,'./dist'),
    compress: true,//服务端压缩文件,保证服务器到浏览器的传输是压缩的 浏览器网络中出现content-Encoding:gzip,
    //自己设置过程中发现如果没有向服务器请求的代码,即使设置了,浏览器也不会出现content-Encoding:gzip,
    port:3000,//更改端口号
    // 配置响应头
    headers:{
      'X-Access-Token':'abc123'
    },
    // 开启代理 例如我们的客户端地址是在http://localhost:3000/
    // 假如我们的接口来自http://localhost:4000/,此时项目中的请求就会跨域
    proxy:{
      '/api':'http://localhost:9000'
    },
    // https:true,//配置为https  由于默认配置使用的是自签名证书,所以浏览器提示不安全,但是我们可以继续访问
    // http2:true,//自带https证书
    historyApiFallback:true,//页面不存在时跳转到根页面
    // host:'0.0.0.0'//开发服务器主机,同一局域网下你的同伴可以通过ip访问你的服务
    //模块热替换与热加载,程序运行中修改模块,无需重新加载整个页面
    hot:true,//热替换
    liveReload:true,//热加载
    client:{
      overlay:false,//浏览器报错覆盖层
    }
},
optimization: {
  usedExports: true,//tree shaking移除 JavaScript 上下文中的死代码,但是移除不完全,需要sideEffects配合
  // 在 package.json 中添加 "sideEffects" 属性如果被标记为无副作用的模块没有被直接导出使用,
  // 打包工具会跳过进行模块的副作用分析评估”。
},
  module:{
    rules:[
        {
            test:/\.js$/,
            exclude:/node_modules/,
            use:{
                loader:'babel-loader',
                options:{
                  presets:[
                    [
                       '@babel/preset-env',
                      {
                        targets:[ //设置babel-polyfill使用的浏览器
                          'last 1 version',
                          '> 1%'
                        ],
                        useBuiltIns:'usage',//按需加载
                        corejs:3 //core版本为3
                      }
                    ]
                    ]
                     
                }
            }
        },
        {
          test:/\.css$/,
          exclude:/node_modules/,
          use:[
            'style-loader',
            {
              loader:'css-loader',
              options:{
                modules:true,//开启css模块
              }
            },
            'postcss-loader',//配合相关插件使用,在postcss。config.js中
          ]
      }
    ]
  },
//   默认为eval,可以设置false关掉,也可以手动设置eval
//   devtool:'eval',
//   devtool:'source-map',
//   devtool:'hidden-source-map',
//   devtool:'inline-source-map',
//   devtool:'eval-source-map',
//   devtool:'cheap-source-map',
//开发环境一般不配置,因为有暴露源码风险,而且体积较大
  // devtool:'cheap-module-source-map',//推荐使用
  plugins: [
    new HtmlWebpackPlugin(),
    new WorkboxPlugin.GenerateSW({
      // 离线环境运行项目
      clientsClaim:true,//快速启用service-worker
      skipWaiting:true,//跳出等待
      //浏览器注销 chrome://serviceworker-internals/
    }),
    // new BundleAnalyzerPlugin() //依赖图
    new webpack.ProvidePlugin({//shimming 预置全局依赖
      _: 'lodash',
    }),
  ],
};

  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值