webpack入门

一、webpack五大核心概念

1、entry

打包的入口,可以是字符串、数组或对象

2、output

打包的输出

3、mode

模式,可以分为开发模式(development)与生产模式(production),默认为生产模式

4、loader

默认只能处理js、json格式的文件,loader的作用就是将其他格式的文件,转换成webpack能够处理的文件

5、plugin

webpack插件,每一个插件都有一个特定的功能,能处理loader无法处理的事情

二、HtmlWebpackPlugin与CleanWebpackPlugin

  • HtmlWebpackPlugin:生成一个html文件,自动打包后的js文件
  • CleanWebpackPlugin:每次打包时自动清除旧的文件,默认清除output.path目录
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.export = {
    entry: {
    page1: './src/page1.js',
    page2: './src/page2.js',
    common: './src/common.js',
  },
  output: {
    path: './dist',
    filename: '[chunkhash].js'
  },
  plugin: [
    new HtmlWebpackPlugin({
        filename: 'index.html',  // 生成html的文件名
      template: './src/template.html',  // 指定模版
      title: 'this is title',  // 设置html的title,可在指定模版中通过ejs语法引入
      inject: true,  // 默认值,script标签位于body底部,可选值为body、header、false(表示不自动引入)
      hash: false,  // true表示引入js文件后面添加hash值作为参数
      chunks:L [page1, common], //  多入口打包会有多个文件,默认引入全部,此配置表示只引入page1,common
      minify: {
        collapseWhitespace: true,  // 去除空格
        minifyCSS: true,  // 压缩html内联的css
        minifyJS: true,  // 压缩html内联的js
        removeComments: true  // 移除注释
      }
    }),
    new CleanWebpackPlugin(),
  ]
}

三、处理项目中的样式文件

webpack默认无法处理css、less、scss等文件,需要借助插件来处理项目中的样式文件

  • npm i css-loader mini-css-extract-plugin sass-loader node-sass -D
  • npm i optimize-css-assets-webpack-plugin -D
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
module.export = {
    ...
  module: {
    rules: [
      {
        test: /\.(css|scss)$/,
        use: [
            MiniCssExtractPlugin,
          'css-loader',
          'sass-loader',
        ]
      }
    ]
  },
  plugins: [
    // 将css单独插入html中
    new MiniCssExtractPlugin(),
    // 压缩css大小
    new OptimizeCssAssetsPlugin,
    // 每次打包先清除dist文件夹
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin()
  ]
}

四、处理项目中的图片

npm i file-loader html-loader url-loader image-webpack-loader -D

  • file-loader 处理图片
  • html-loader 处理html中src引入的图片
  • url-loader 将图片转为base64,压缩图片体积
  • image-webpack-loader,压缩图片体积,不能与url-loader一起使用
module.exports = {
    ...
  output: {
    publicPath: './'
  },
  plugins: [
    new MiniCssExtractPlugin({
        filename: 'style/[name].css'
    })
  ]
  module: {
    rules: [
      {
        test: /\.(scss|css)$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../'
            },
          },
          'css-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.(png|jpeg|gif|svg|jpg)/,
        use: {
          loader: 'url-loader',
          options: {
            name: '[name]-[contenthash:10].[ext]', // ext表示文件的后缀名
            esModule: false, // 不使用es6的模块化语法
            outputPath: 'images',
            limit: 10 * 1024, // 表示小于10kb的图片会被base64编码
          },
        },
      },
      {
        test: '/\.html$/',
        use: 'html-loader',
      },
    ],
  },
}

五、理解name、hash、chunkhash、contenthash

  • name:chunk name,chunk的名称,多入口chunkname为其key值,单入口不指定默认为main,异步加载的模块默认为数字
  • hash:每次打包生成的hash,项目中任意与打包相关的文件内容改变,此hash就会改变
  • chunkhash:根据chunk的内容生成的hash
  • contenthash:单个输出文件内容的hash

六、devServer的使用

webpack-dev-server是webpack官方提供的一个小型express服务器,它可以为webpack打包生成的资源文件提供web服务

首先安装:npm i webpack-dev-server -D

在package.json中配置

"script": {
    ...
  "start": "webpack-dev-server"
}
// webpack.config.js
module.exports = {
    ...
  devServer: {
    contentBase: path.resolve(__dirname, 'public'),  // 告诉服务器从哪里提供内容,默认为当前工作目录
    watchContentBase: true,  // 监视contentBase里面的内容,一旦变化就reload
    watchOptions: {
        ignore: ''  // 忽略哪些文件的变化
    },
    historyApiFallback: true,  // 请求的资源不存在时返回index.html,比如vue-router的history模式
    clientLogLevel: 'none',  // 不要显示启动日志信息
    overlay: false,  // 如果出错,不要全屏提示
    progress: true,  // 控制台输出运行进度
    compress: true,  // 启用gzip压缩
    open: true,  // 自动打开浏览器
    host: '0.0.0.0',  // 如果希望被局域网访问,设置为0.0.0.0,默认为localhost
    port: '8888',  // 端口,默认8080
    useLocalIp: true,  // 使用本地ip,如果host设置0.0.0.0,这里需要设置为true
    hot: true,  // 开启热更新
    proxy: {  // 设置代理
        'api': {  // 当url中含有/api时就会使用这里设置的代理
        target: 'http://xxx.com',  // 目标服务器地址
        changeOrigin: true,  // 跨域
        ws: true,  // 代理websocket
        pathRewrite: {
            '^/api': ''  // url重写,将url里面的/api去掉
        }
      }
    }
  }
}

七、js兼容性处理

由于ie浏览器无法识别高阶语法,因此需要使用babel来转换这些语法

  • babel-loader
  • @babel/core (babel核心库、核心api)
  • @babel/preset-env (babel预设,babel是插件化的,转换不同的语法,需要不同的插件,预设的作用就是按需引入)
    npm i babel-loader @babel/core @babel/preset-env -D
// webpack.config.js
module.exports = {
    module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,  // 不处理node_modules中的文件
        use: {
            loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
}

还要安装@babel/polyfill来处理ES6中的一些语法

@babel/polyfill 其实是 core-js2 与 regenerator-runtime 组成的一个集成包,使用 core-js2,则安装 @babel/polyfill,使用 core-js3 则安装 core-js 与 regenerator-runtime ,以 core-js3 为例

npm i core-js regenerator-runtime -S

// webpack.config.js
module.exports = {
    module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,  // 不处理node_modules中的文件
        use: [
          {
            loader: 'babel-loader',
            options: {
                presets: [
                ['@bebel/preset-env', {
                    modules: false,  // 对ES6模块文件不做转化,以便使用 tree shaking
                  useBuiltIns: usage,  // 取值可以是false,'entry','usage'
                  corejs: 3,  // corejs版本号
                  targets: {}  // 需要兼容的浏览器,未配置,取 browserslist中的值
                }]
              ]
            }
          }
        ]
      }
    ]
  }
}

关于useBuiltIns取值的说明

  • false:需要在js文件顶部引入,不需要指定corejs版本号
// <--- core-js2 --->
// import "@babel/polyfill";
// <--- core-js3 --->
import "core-js/stable";
import "regenerator-runtime/runtime";
  • entry:需要在js文件顶部引入,需要指定corejs版本号,根据配置的浏览器,打包浏览器不兼容的内容
  • usage:不需要在js文件顶部引入,需要指定corejs版本号,根据配置的浏览器,以及代码中用到的API来按需打包
    当项目中的js越来越多,babel转换耗时越来越长,可以使用babel缓存及多进程打包来提高速度,安装thred-loader
// webpack.config.js
module.exports = {
    module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,  // 不处理node_modules中的文件
        use: [
          {
            loader: 'thred-loader',  // 耗时比较长的 loader 才需要多进程,否则只会更慢
            options: {
                workers: 2  // 进程数
            }
          },
          {
            loader: 'babel-loader',
            options: {
                presets: [
                ['@bebel/preset-env', {
                    modules: false,  // 对ES6模块文件不做转化,以便使用 tree shaking
                  useBuiltIns: usage,  // 取值可以是false,'entry','usage'
                  corejs: 3,  // corejs版本号
                  targets: {}  // 需要兼容的浏览器,未配置,取 browserslist中的值
                }]
              ]
            }
          }
        ]
      }
    ]
  }
}

八、其他配置

1、resolve:设置模块如何被解析

alias:为路径设置别名,让引入变得更简单

// webpack.config.js
module.exports = {
    resolve: {
    alias: {
        '@': path.resolve(__dirname, 'src'),
      // $ 匹配结尾,不会影响vue/xxx的路径,表示项目中引入的vue为运行时版本
      'vue$': 'vue/dist/vue.runtime.js'
    }
  }
}
extensions: 引入哪些类型的文件时可以省略后缀名
resolve: {
  // 默认为['.js', '.json'],表示引入js、json、vue文件时不需要写后缀名
    extensions: ['.js', '.json', '.vue']
}
2、externals:设置某些库不被打包,从外部获取
// index.html 中 body 底部添加
<body>
  <% for (let src of htmlWebpackPlugin.options.cdnList) { %>
    <script src="<%= src %>"></script>
  <% } %>
  <!-- 直接写死,与上面二选一,推荐上面的方式 -->
  <script src="https://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</body>

// webpack.config.js 添加下面内容
module.exports = {
  externals: {
    jquery: "jQuery" // key 为引入的包名,value 为全局变量名
  },
  plugins: [
    new HtmlWebpackPlugin({
      // 用来在 html 中通过 script 引入,cdnList 为自定义变量。若直接写死则不需要此配置
      cdnList: ["https://libs.baidu.com/jquery/2.0.0/jquery.min.js"]
    })
  ]
}
3、watch:初始构建之后,继续监听任何已解析文件的更改

将此参数设置为 true,使用 webpack 打包之后,每当有文件内容发生变化,就会自动重新打包(devServer默认开启)

module.exports = {
  watch: true,
  watchOptions: {
    aggregateTimeout: 300, // 延时 300ms 打包,防抖
    ignored: /node_modules/, // 忽略监听,也可以是 anymatch 模式,例: "files/**/*.js"
    poll: true // 开启轮询模式,如果值为数字,表示轮询的间隔,单位毫秒
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值