阅读 2045

9102了,快来了解webpack4!

前言

在当今的前端开发中,我们使用的打包工具可能会有很多种,当然webpack就是其中一种,那么webpack中的配置实际上是很多的,所以今天来整理下常用的配置以及它的作用。

如何开始

我们创建一个空的文件夹,然后使用npm init webpack-demo,下面一路回车,然后他会在我们的文件夹下创建一个package.json这样的文件

在当前项目中安装webpack4

我们可以执行这条命令: npm install webpack-cli webpack -D

那么这里假设webpack最新版本号是:4.1.2,如果我们不想安装最新的版本,而是我们人工选择,该如何选择呢?

npm info webpack 执行这条命令后控制台就会列出webpack的所有可用版本

那么找到我们想要安装的版本,记录下版本号(假设我们想安装webpack4.16.5这个版本)

我们就可以使用npm install webpack@4.16.5 -D安装指定版本的webpack了。

开始配置

webpack4中官方已经提供了默认配置,但有时并不是那么符合我们的需求,我们想自行配置,那么我们可以在项目目录下创建webpack.config.js文件,来书写自己的配置

配置介绍

const path = require('path')
module.exports = {
    mode: 'production',
    entry: {
        main: './index.js'
    },
    output:{
        filename: 'bundle.js',
        path: path.resolve(__dirname,'build')
    }
}
复制代码

那么上面的配置意思是告诉webpack应该从 index.js文件开始打包,打包后生成的文件应该放到build文件夹下,生成的文件名叫bundle.js,这里需要注意的是path必须是绝对路径,所以这块我们需要引入nodejspath模块来辅助我们,如果modeproduction那么意味着打包后的js是被压缩过的代码,当然这里填写development的话代码就不会被压缩了

Loader

那么我们为什么需要使用Loader,是因为webapck在默认情况下,他只知道如何打包JS文件,而不知道如何打包图片,字体等其他类型文件,所以在这里我们就需要借助Loader来辅助webpack在打包时对特殊文件进行处理。

图片文件打包配置

我们在上面的基础之上进行配置

const path = require('path')
module.exports = {
    mode: 'development',
    entry: {
        main: './index.js'
    },
    module:{
      rules: [{
          test: /\.jpg$/,
          use: {
            loader:'file-loader'
          }
        }]  
    },
    output:{
        filename: 'bundle.js',
        path: path.resolve(__dirname,'build')
    }
}
复制代码

那么在这里我们增加了一个module配置,这里其实就是告诉webpack如何打包模块,rules就是打包模块的规则,test里写的是匹配规则,use是指使用哪个loader进行处理,那么这里我们使用了官方推荐的file-loader,那么这个loader,其实它就可以对图片之类的文件进行处理,所以这样配置我们就可以成功的进行打包啦。

别忘记安装file-loader的依赖,npm install file-loader -D

webpack-dev-server配置

使用devserver可以提高我们的开发效率,比如热更新

devServer: {
    contentBase: './dist',
    open: 'true',
    port: 8080,
    hot: true,
    hotOnly:true
  },
复制代码

css打包配置

module: {
    rules: [
      {
        test: /\.(css|scss)$/,
        use: ['style-loader', {
          loader: 'css-loader',
          options: {
            importLoaders: 2
          }
        },
          'sass-loader',
          'postcss-loader']
      }
    ]
  },
复制代码

这里需要注意如果有多个loader,那么loader其实是从下到上执行,从右到左执行,但这里的postcss-loader又是什么呢,他其实是为我们的css加上厂商兼容前缀的。 这里的配置大概意思是说:我先用postcss-loader为css加上厂商前缀,然后交给sass-loader把我们的sass编译为普通css,再交给我们的css-loader,然后再交给我们的style-loader负责把我们的样式挂载到页面上。

importLoaders: 2这个又是什么意思呢?

我们也许会有如下场景: 一个scss文件里import了另一个scss文件,那么有可能在打包时就不会走下面的两个loader(sass-loader,postcss-loader),而是直接走了css-loader,那么如果我们希望被引入的scss文件也走下面两个loader就应该配置这个配置,让webpack明白该怎么做处理。

打包iconfont等字体文件

module: {
    rules: [
      {
        test: /\.(eot|ttf|svg|woff|woff2)$/,
        use: {
          loader: 'file-loader'
        }
      }]
  }
复制代码

我们可以借助file-loader对文件进行打包

Plugins

简介

plugin可以在webpack运行到某个时刻的时候,帮你做一些事情

HtmlwebpackPlugin

const HtmlwebpackPlugin = require('html-webpack-plugin');
plugins: [new HtmlwebpackPlugin({
    template: 'src/index.html',
    filename:'index.html'
})]
复制代码

这里我们使用了一个HtmlwebpackPlugin插件 ,我们指定了template使用哪个文件,并指定打包后的文件名

CleanwebpackPlugin

const CleanwebpackPlugin = require('clean-webpack-plugin');
plugins: [new HtmlwebpackPlugin({
    template: 'src/index.html',
    filename:'index.html'
}),new CleanwebpackPlugin()]
复制代码

这个CleanwebpackPlugin可以在打包时帮我们删除dist文件夹下所有内容。减少了我们手动操作的频率

babel

我们的项目难免要做一些兼容性处理,所以我们要借助babel把我们的es6代码转换成es5代码 我们首先应该安装@babel/preset-env和babel-polyfill依赖

module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, '../src'),
        loader: 'babel-loader',
        options:{
            presets:[['@babel/preset-env',{
                useBuiltIns:"usage"
            }]]
        }
      }]
}
复制代码

这块的配置'@babel/preset-env'这个其实只是转换es6的语法为es5的语法,我们还需要在main.js最上方引入babel-polyfill,这个意思是把一些es6中没有的函数用es5全部模拟一遍, useBuiltIns:"usage"这个的意思是在模拟过程中,只模拟我们项目中只模拟项目中用到的es6的函数。

tree-shaking

在webpack中我们可以对我们已经引入但未使用的代码做‘摇树’处理(不过需要注意的是这个功能只对esModule起作用) 我们需要在package.json里配置:sideEffects:[‘babel-polyfill’] 然后打包就可以把除过babel-polyfill的无引用的全部都剔除掉了

code-splitting

我们需要把打包出来的文件拆分成好多个小文件,防止在更新代码时一次性更新了很大的一个文件,导致用户那边的缓存失效,又要重新下载很大的文件

optimization: {
    runtimeChunk: {
      name: 'runtime'
    },
    splitChunks: {
      chunks: 'all',// 同步异步都打包
      cacheGroups: { 
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          filename: 'vendors.js'
        }
      }
    }
  },
复制代码

css文件代码分割

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
这两个插件我们得安装
optimization: {
    usedExports: true, // tree shaking
    minimizer: [new OptimizeCssAssetsPlugin({})]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[name].chunk.css'
    })
]
复制代码
文章分类
前端
文章标签