封面 pid: 59743937

通过项目入口,递归地收集依赖关系,将项目打包,顺便做下代码转化和文件优化。简单的说,这就是webpack的功能。
在此记录webpack4的学习记录,作为开始,先安装webpack基础包webpack、webpack-cli

基础

使用entry、output字段指定webpack的项目入口和打包输出

module.exports = {
  mode:'developement',
  entry:'./src/index.js', //入口
  output:{
    filename:'build.[hash:8].js', //输出文件名
    path:path.resolve(__dirname,'dist') //输出路径(需绝对)
  }
}

如果要使用开发服务器,npm安装webpack-dev-server,使用devServer字段进行配置,启动命令为webpack-dev-server

module.exports = {
  devServer:{
    port:8080, //端口
    progress:true, 
    contentBase:'./dist', //根目录
    compress:true,

    proxy: { //代理转发
      '/root': { // /root开头的请求代理到target
        target: 'http://localhost',
        changeOrigin:true,
        pathRewrite: { //代理后重写url,去除/root
          '^/root' : ''
        }
      }
    }
  }
}

如果需要打包html模板,npm安装插件html-webpack-plugin,创建插件实例并使用。webpack中插件在配置中对应plugins字段,值是一个数组

const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  plugins:[
    new HtmlWebpackPlugin({
      template: './src/index.html', //模板路径
      filename: 'index.html', //输出文件名
      minify: {
        collapseWhitespace: true, //消除空行
      },
      hash: true
    })
  ]
}

resolve字段配置模块的导入(import)设置

module.exports = {
  resolve: {
    //指定解析的模块
    modules: [path.resolve('node_modules')],
    //省略后缀,import 'index' 如果不存在依次检查 index.js, index.css
    extensions: ['.js','.css']
    //别名替换,导入'@/index.js' 等价于'./src/index.js' 
    alias: {
      '@': './src'
    }
  }
}

样式处理

webpack中对代码进行转换的部分称为loader,在配置中对应module字段,值是一个对象。module对象中rules数组描述了各类文件的处理方法和顺序。loader是有处理顺序的,默认从左到右,从下到上

样式处理loader主要用到postcss-loader,css-loader,前者自动添加浏览器前缀,后者处理@import语法。插件主要用到mini-css-extract-plugin,用于将css抽离成独立文件供引用。npm安装后进行如下配置

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {

  plugins:[
    new MiniCssExtractPlugin({
      filename: 'css/main.css' //抽离输出路径
    })
  ],

  module:{
    rules:[//每个rule处理一类文件
      {
        test:/\.css$/, //处理css文件
        use:[
          MiniCssExtractPlugin.loader,
          'css-loader',
          {//需要详细配置的话使用对象
            loader:'postcss-loader',
            options:{
                plugins:[
                    require('autoprefixer')
                ]
            }
          }
        ]
      }
    ]
  }
}

css压缩需要用到插件optimize-css-assets-webpack-plugin,使用时new入plugins字段即可。

JS代码处理

ES6代码转换需要安装babel-loader及以下包

  • @babel/core
  • @babel/preset-env
  • @babel/plugin-transform-runtime
module.export = {
  module:{
    rules:[
      {
        test: /\.js$/, //处理js文件
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-env'
              ],
              plugins: [
                '@babel/plugin-transform-runtime'
              ]
            }
          }
        ],
        include: path.resolve(__dirname,'src'),
        exclude: /node_modules/
      }
    ]
  }
}

变量引入

如果你在大部分文件都要导入一个模块,可以考虑在每个文件中注入该模块

let webpack =require('webpack');
module.exports = {
  plugins:[
    new webpack.ProvidePlugin({
      $: 'jquery' //注入jquery为$
    })
  ]
}

如果外链已提供模块,希望只导入而不打包,需要在external进行声明

module.exports = {
  externals: {
    jquery: '$' //对于jquery的导入,用$引用它
  }
}

文件打包

如果要为除css、js外其他文件进行打包,实现引用地址的映射,需要安装file-loader,url-loader

module.exports = {
  module:{
    rules:[
      {
        test: /\.(png|jpg|gif)$/, 
        use: {
          loader: 'url-loader',
          options: {
            limit: 1000, //低于该值被直接base64编码
            name:'[name].[ext]',
            outputPath: '/img/', //打包到
            //publicPath: 'https://oshinonya.com' //引用头加上域名
          }
        }
      },
    ]
  }
}

多入口多出口

module.exports = {
  entry: {
    home: './src/index.js',
    other: './src/other.js'
  },
  output:{
    filename: '[name].js',
    path: path.resolve(__dirname,'dist')
  },

  plugins:[
    new HtmlWpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
      chunks: ['home'] //插入的代码块,对应entry.keys
    }),
    new HtmlWpackPlugin({
      template: './src/index.html',
      filename: 'other.html',
      chunks: ['other']
    })
  ]
}

环境区分&环境变量

创建多个webpack配置文件供不同环境使用:

  • webpack.base.js,公共配置
  • webpack.dev.js,开发配置
  • webpack.prod.js,生产配置

并在开发/生产配置中整合公共配置

// webpack.prod.js
let {smart} = require('webpack-merge')
let base = require('./webpack.base.js')

module.exports = smart(base,{
  mode:'production'
  //其他配置
})

使用插件webpack.DefinePlugin定义环境变量,可以在模块中直接使用

let webpack = require('webpack');
module.exports = {
  plugins:[
    new webpack.DefinePlugin({
      BASE_URL: JSON.stringify('https://oshinonya.com'),
      IS_PROD: 'true'
    })
  ]
})

代码抽离与分割

全部源码打包成一个文件配合缓存确实一劳永逸,但网络不好的话首屏时间会很长,作为妥协,可以适当地让一些公共模块单独抽离出来。在optimization字段进行配置

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 30000,//触发分割的最低体积
      minChunks: 2,//触发分割的引用次数
      cacheGroups: {
        vendors: {//第三方模块
          test: /[\\/]node_modules[\\/]/,
          priority: -10 //优先级更高
        },
        default: {//自己的代码
          test: /[\\/]src[\\/]/,
          priority: -20
        }
      }
    }
  }
}

    添加新评论 | #

    Markdown Supported
    简单数学题:NaN + NaN =
    表情

    Comments | ?? 条评论

    • 单身为狗 22 年

    • 朝循以始 夜继以终

    • Blog: Von by Bersder

    • Alive: 0 天 0 小时 0 分

    Support:

    frame ssr server DNS music player

    © 2019-2021 ᛟᛊᚺᛁᚾᛟ

    back2top