Webpack介绍与基础配置

489 阅读4分钟

Webpack介绍

官网 www.webpackjs.com/concepts/

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

构建就是把源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码,包括如下内容。

  • 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。
  • 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
  • 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
  • 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功- 能把模块分类合并成一个文件。
  • 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
  • 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
  • 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

webpack核心概念

  • Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,递归查找依赖模块进行打包。
  • Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
  • Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
  • Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。

webpack中一切皆模块,会将所有类型的文件转换后按照js模块来加载

配置webpack

初始化项目安装依赖模块

npm init -y
npm i webpack webpack-cli webpack-dev-server -D

webpack配置文件 webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',
  // webpack打包时从入口出发
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
}

mode

  • development
  • production production会自动做一些优化

output 出口

  • path 打包文件的输出路径
  • filename: 'bundle.[hash].[chunkHash].[contentHash].js' 输出的文件名
  • hash 一次打包的hash值
  • chunkHash 模块的hash
  • contentHash 内容的hash

devtool 开发工具

  • eval 使用eval包裹模块代码
  • source-map 产生.map文件
  • inline 将.map作为DataURI嵌入,不单独生成.map文件
  • cheap 不包含列信息,也不包含loader的sourcemap
  • module 包含loader的sourcemap

devServer 配置开发服务器

  • contentBase 开发服务器在哪个目录下启动
  • port 端口号
  • proxy 代理
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    host: 'localhost',
    port: 5000,
    proxy: {
      '/api': {
        target: 'http://localhost:4000',
        pathRewrite: { '^/api': '' },
      },
    },
  }

module 配置模块,主要用来配置不同文件的加载器

plugins 配置插件

  • npm i html-webpack-plugin -D 处理html模板
  • npm i clean-webpack-plugin -D 打包前清理目录的插件

编译解析react JSX语法

  • npm i react react-dom -S
  • npm i babel-loader @babel/core @babel/preset-env @babel/preset-react -D

Loader的几种写法

  • test 正则匹配
  • loader 匹配到的文件用那种loader解析
  • loader 支持 字符串、数组、对象
  • include 包含文件夹
  • exclude 排除文件夹

加载React js代码转换

    {
    test: /\.jsx?$/,
    use: {
        loader: 'babel-loader',
        options:{
         "presets": ["@babel/preset-env", "@babel/preset-react"],
        }
    },
    include: path.join(__dirname,'src'),
    exclude:/node_modules/
}

加载css, loader的执行顺序 从右向左,从下向上

  • css-loader 解析css
  • style-loader 将 css 插入html
    {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      }

加载scss

  • sass
  • sass-loader
    {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
    }

处理CSS3属性前缀

  • postcss-loader
  • autoprefixer
    {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader'],
      }
  • postcss配置文件 postcss.config.js
module.exports = {
  plugins: [require('autoprefixer')],
};

加载图片资源

  • url-loader 解决CSS等文件中的引入图片路径问题
  • file-loader 当图片小于limit的时候会把图片BASE64编码,大于limit参数的时候还是使用file-loader 进行拷贝
{
        test: /.(png|jpg|gif|svg)$/,
        use: [
          {
            loader: 'url-loader',
            options: { limit: 1024 * 8 },
          },
        ],
      }

抽离css插件

  • 因为CSS的下载和JS可以并行,当一个HTML文件很大的时候,我们可以把CSS单独提取出来加载
  • mini-css-extract-plugin
    plugins: [
        new MiniCssExtractPlugin({
          filename: '[name].css',
        })
    ]
    
    {
        test: /\.css$/,
        use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'postcss-loader'],
      }

压缩JS和CSS

  • npm i uglifyjs-webpack-plugin terser-webpack-plugin optimize-css-assets-webpack-plugin -D
optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        cache: true,
      }),
      //压缩css资源的
      new OptimizeCSSAssetsPlugin({
        assetNameRegExp: /\.css$/g,
        //cssnano是PostCSS的CSS优化和分解插件。cssnano采用格式很好的CSS,并通过许多优化,以确保最终的生产环境尽可能小。
        cssProcessor: require('cssnano'),
      }),
    ],
  }

css和image存放单独目录

  • outputPath 输出路径
  • publicPath指定的是构建后在html里的路径
    output: {
        path: path.resolve(__dirname,'dist'),
        filename: 'bundle.js',
+        publicPath:'/'
    },

{
  test:/\.(jpg|jpeg|png|bmp|gif|svg|ttf|woff|woff2|eot)/,
  use:[
        {
          loader:'url-loader',
          options:{
              limit: 4096,
+              outputPath: 'images',
+              publicPath:'/images'
          }
        }
     ]
}

new MiniCssExtractPlugin({
+      filename: 'css/[name].css',
+      options: {
+        publicPath: '/',
+      },
    }),

Resolve

  • extensions 指定extension之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配
  • alias 配置别名可以加快webpack查找模块的速度
resolve: {
  extensions: [".js",".jsx",".json",".css"],
  alias: {
      "@": path.resolve(__dirname, 'src'),
  }
},

代码:代码传送门