学习前端框架vue、react等之前了解一下打包工具webpack会利于后面框架的学习。在本篇主要讲解webpack的使用,以及各种配置等。

webpack

关于webpack具体介绍请参考webpack中文网查看。

安装webpack

使用npm安装,一般只是开发时使用所以使用下面的代码安装webpackwebpack-cli

npm i webpack webpack-cli -D

webpack的四个核心概念

  • 入口(entry): entry 对象是用于 webpack 查找启动并构建 bundle。其上下文是入口文件所处的目录的绝对路径的字符串。
  • 输出(output): 打包后的文件输出目录,默认值为dist,必须是绝对路径(使用 Node.js 的 path 模块)
  • loader: 一种对css,js等各种文件的处理器,可将这些文件中的样式,函数,变量等根据规则合并打包到一起。
  • 插件(plugins): 对html等部分文件会有专门等插件用来对其进行处理,如代码压缩、注释清理等。

配置

webpack的默认配置文件名是webpack.config.js

const {resolve, join} = require('path');
// 需要使用npm安装到开发依赖中: npm i html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 需要使用npm安装到开发依赖中: npm i mini-css-extract-plugin -D
// 该插件可以将css资源打包成单独的css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 压缩css插件: npm i optimize-css-assets-webpack-plugin -D
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

// 去除无用css插件: npm i purgecss-webpack-plugin -D
const PurgecssPlugin = require('purgecss-webpack-plugin');
const glob = require('glob');
const PATHS = {src: join(__dirname, 'src')}

module.exports = {
  mode: "development", // "production" | "development" | "none"

  entry: "./app/entry", // string | object | array
  output: {
      // webpack 如何输出结果的相关选项
    
      path: resolve(__dirname, "dist"), // string
      // 所有输出文件的目标路径
      // 必须是绝对路径(使用 Node.js 的 path 模块)

      filename: "bundle.js", // string,多入口时使用"[name].js"或者"[name].[hash].js"(默认输出格式)

      publicPath: "/assets/", // string|""|"https://cdn.example.com/"
      // 输出解析文件的目录,url 相对于 HTML 页面
    },
  module: {
    rules: [
      //npm安装的loader:npm i css-loader style-loader less-loader node-sass sass-loader -D
      // loader要想起作用需要在entry入口文件中使用require函数或者import方式引入,最终以style标签到方式插入html头中
      {test: /\.css$/, use: ['style-loader', 'css-loader']}, //从右到左处理css资源
      {test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, //从右到左处理less资源
      {test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader']}, //从右到左处理sass资源
		  // {test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader']}, //从右到左处理,最终打包成单独的css文件
      // 处理css的兼容性:npm i post-loader postcss-preset-env -D
		  // {test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'post-loader']}, //从右到左处理,最终打包成单独的css文件(处理css的兼容性)
      // 处理图片资源:npm i url-loader file-loader
      // 可以将图片资源路径处理成打包后的路径
      {
        test: /\.(png|jpg|jpeg|gif)$/, 
        loader: 'url-loader', 
        options: {
          publicPath: 'images/',
          outputPath: 'images/',
          limit: 1024 * 8,// 即小于8k的图片会转成base64字符串,大于的则以独立文件输出
          name: '[name].[hash:10].[ext]'// 默认使用hash作为名称,:{num}将hash值截短,[name]输出原始名称
        }
      },
      // 将html中的图片使用url-loader处理,安装:npm i html-loader -D
      {
        test: /\.html$/, 
        loader: 'html-loader'
      },
      // 将上面处理过的文件格式以外的文件直接原样打包到output中
      {
        exclude: /\.(js|json|html|css|less|scss|png|jpg|jpeg|gif)$/,
        loader: 'file-loader',
        options: {
          publicPath: 'font/',
          outputPath: 'font/',
          name: '[name].[hash:8].[ext]'
        }
      },
      // 检查js代码规范的loader
      {
        test: /\.js$/, 
        loader: 'eslint-loader',
        exclude: '/node_modules/',// 只检查自己项目内容js代码不检查第三方库
        options: {
          fix: true
        }
      }
    ]
  },
  plugins: [
    // 默认创建一个空的,目的是自动引入打包的资源(js,css等)
    new HtmlWebpackPlugin({
    	template: "src/index.html",// 入口名
    	filename: "demo.html",// 输出文件名
    	chunks: ["index", "cart"]// 多个entry入口时,object中的字段名,资源从右到左依次加载到html中
    	minify: {
    		collapseWhitespace: true, // 移除空格 
    		removeComments: true// 移除注释
    	}
    }),
    // 打成单独css文件的插件
    new MiniCssExtractPlugin({
      filename: "[name].css"
    }),
    // 默认压缩一般就可以达到想要的效果
    new OptimizeCssAssetsPlugin(),
    // 去除无用的css代码
    new PurgecssPlugin({
      paths: glob.sync(`${PATHS.src}/**/*`, {nodir: true})
    })
  ],
// webpack-dev-server配置
  target: "web",// 在webpack5以后需要此选项才可以自动刷新浏览器
  devServer: {
    port: 3000,// 服务运行的端口
    compress: true,//执行编译
    open: true,// 自动打开默认浏览器
    hot: true//热加载
  }
};

css兼容性配置

使用postcss-preset-env插件处理,新版webpack一般放在单独的配置文件postcss.config.js

module.exports = {
  plugins: [
    require('postcss-preset-env')()
  ]
};

还需要在package.json中加入浏览器支持配置,然后根据这份配置去做兼容性。browserslist可以是objectarrayobject时支持分别对开发(development)和生产(production)环境支持的浏览器进行配置。

  • array
{
  "browserslist": [
    "> 1%",// 支持90%的浏览器
    "last 2 versions",// 最新的两个版本
    "not dead"//不支持死掉的浏览器
  ]
}
  • object
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }

最后还需要post-loader的处理,参考配置章节

代码风格检查插件

需要使用eslint相关的组件来支持。安装代码如下:

npm i eslint eslint-loader eslint-config-airbnb-base eslint-plugin-import -D

以及在package.json包中加入配置

  "eslintConfig": {
    extends: "airbnb-base"
  }
}

最后使用eslint-loader, 参考配置章节

webpack的开发服务器

也就是使用webpack搭建的一个开发用的服务器,可以实时编辑,实时刷新浏览器,免得每次写完后打包到目录中,然后放到服务器上运行。这个可以只是内存中编译,速度也会非常快。

需要安装webpack-dev-server组件。

npm i webpack-dev-server -D

然后参考配置章节中的最后一部分。

最后运行webpack serve --mode development,然后访问配置中的端口就行。还可以把运行命令配置在package.json中的scripts里,然后运行npm run {key}这样的命令即可。(为scripts对象中的key)。

代码优化

去除css中的无用代码,js中的无用代码等。js的去除只要使用webpack的生产模式打包就自动去掉(新版),而css要想实现去除无用代码还需要purgecss-webpack-plugin插件的支持。详情参考配置章节中关于该插件的配置。