乐趣区

关于前端:带着这种思想我快速高效的学会了webpack开发环境配置

前言

咱们在应用 webpack 时,常常会看到相似以下构造:

build
├── webpack.common.js
└── webpack.dev.js
└── webpack.prod.js

很多时候,webpack的配置咱们根本复制粘贴过去的,没有想过为什么咱们要把配置文件拆解成这么多。因而,当咱们本人去学习配置 webpack 时,咱们常常会呈现以下等问题:

  • 开发环境构建速度慢
  • 打包后页面空白
  • 资源找不到

其实这些问题,都源于咱们:

  • 不了解 webpack 构建开发环境、生产环境,两种环境配置的思维差别
  • 对两种环境输入的文件目录,脑海中没有一个清晰的了解

所以本文还是跟以前一样,不会一味的把配置复制过去,而是心愿 总结相干办法,让大家更好学会配置。

后期筹备

因为讲的是配置,所以心愿你对 webpack 有一些根底。如果你只是刚学习 webpack,倡议先浏览一下前两篇文章, 尤其是第二篇

  1. 弄懂这几个概念后,我对 webpack 有了更新的了解:学习应用 webpack 时波及到的一些概念,让咱们对 webpack 整体有个大抵的理解
  2. 有了这些办法,webpack 你也能够本人配:总结配置 webpack 时的一些办法。通过这些办法,咱们能够很好的了解 webpack 的一些根底配置该如何配置

学习纲要

这篇文章次要解说:

  • webpack开发环境配置的核心思想
  • 依据核心思想,实现一个开发环境配置
  • 解析 devServer 配置项一些容易混同的点
  • 总结 webpack 开发环境配置外围

备注

文章波及到的案例曾经上传到 github:

  • 为了浏览不便,文章只贴了相干代码,倡议 fork 一下,看看残缺代码;或者跟着文章一起边看边敲,这样印象会更粗浅一些
  • 创作不易,如果感觉有帮忙的话,欢送star🌟

开发环境核心思想

在上文咱们提到,咱们在应用 webpack 时,常常会看到相似以下目录:

build
├── webpack.common.js
└── webpack.dev.js
└── webpack.prod.js

为什么咱们须要把配置文件拆解成这么多,那么繁琐呢?

咱们先回顾一下,在咱们在理论开发中,为了我的项目可能稳固平安上线,咱们个别会分好几个环境:

  • 开发环境:在本地进行开发,调试的环境
  • 测试环境:咱们在本地开发实现后,将代码部署到咱们的测试服务器,进行测试
  • 生产环境:测试通过,将代码部署到正式服务器,正式上线

有些更严格的测试,还会有预生产环境等

咱们的配置应该对环境具备针对性,因而不同的环境,咱们的配置当然不能千篇一律。

目标

咱们要先分明开发环境基本的目标是什么。

开发环境的基本目标,就是在开发过程中,能疾速定位到问题,更快能看到成果调试,进步开发效率。

尤其作为前端,离不开跟视觉打交道。咱们巴不得 Ctrl+S 后,立马出成果,不便咱们疾速调试。试想一下,如果每次写完一个成果,要等上几秒钟能力看到,这会不会把咱们逼疯?

思维

因而,为了能让咱们尽快看到成果调试,缩小 webpack 的编译过程,开发环境,配置应该所有从简

  • 对款式,咱们不须要拆散,间接用 style-loader 插入到<head />
  • jsimgmediafont 等前端资源文件,不须要分包
  • 开启source map,不便定位问题
  • 应用 webpack 提供的 devServer 配置项,进行本地开发
  • 不要压缩代码
  • 不必没必要的 loaderplugins

开发环境配置,也因人而异,以上是我的做法。然而咱们要记得,开发环境,配置应该所有从简,为了让咱们可能更快看到成果,进步开发效率

开发环境配置

初体验

通过前一篇文章的解说,置信大家对 webpack 的根底配置:

  • 解决css、less、前端资源等文件
  • 编译 es6+ 语法及api
  • 解决 html 文件

曾经把握了相干的配置办法,并且咱们还总结了一份根底的配置,不太分明的同学能够看一下先,这个根底配置还是蛮重要的。

ok,那咱们先用 learn-08 这个案例来体验一下如何进行本地开发调试。为了尽量贴近咱们事实中开发的我的项目,案例里会:

  • html 外面援用图片
  • 应用 less 外面援用图片
  • js 里应用es6+,动静加载图片
  • 应用 devServer 配置项

为了浏览不便,具体的源码就不放文章了,大家能够去 github 看

而后进行以下步骤:

  1. 为了语义化,咱们把 webpack 配置文件命名为webpack.dev.js
  2. 应用命令行启动webpack——npm start

    "scripts": {"start": "webpack server --config ./webpack.dev.js"}

运行后果:

咱们会发现:

  • 文件编译解决实现后,不会输入任何文件
  • 此时开启了一个外部服务器(http://192.168.0.196:8080/)。如果咱们的手机与电脑用的同个网络,用手机拜访这个链接,就能看到成果了。这对调试 H5 开发是非常高效的(这次要归功于 deveServer 配置项,后文会有解说)
  • 咱们批改代码后,页面会实时更新

以上简直是咱们想要的高效开发成果。

剖析

初步体验完后,咱们依据上文总结的开发环境配置思维,来看看对开发环境该如何配置:

  • 解析款式不须要拆散出 css 文件,咱们间接将解析进去的款式插入到 <header /> 中:

    module: {
      rules: [
          {test: /.(css|less)$/, 
              use: [
                  'style-loader',
                  'css-loader',
                  'less-loader'
              ]
          },
      ]
    },
  • jsimgmediafont 等前端资源文件,不须要分包:

    output: {path: path.resolve(__dirname, './dist'),
      filename: '[name]-[chunkhash:5].js',
    },
    module: {
      rules: [
          {test: /\.(png|svg|jpg|jpeg|gif)$/i,
              type: 'asset',
              parser: {
                  dataUrlCondition: {maxSize: 1024 * 3 // When the image size is < 3kb it will be converted to base64}
              },
              generator: {filename: '[name]-[hash:5][ext]' // Set the name of the output file
              }
          },
          {
              test: /\.m?js$/,
              exclude: /(node_modules|bower_components)/,
              use: {loader: 'babel-loader'}
          }
      ]
    },
  • 开启source map,不便定位问题;并且不压缩代码:

    {
      mode: 'development',
      devtool: 'inline-cheap-module-source-map'
    }
  • 应用 webpack 提供的 devServer 进行本地开发:

    devServer: {
      static: {directory: path.join(__dirname, 'static'),
      },
    },
  • 没有装置其余多余的 plugin,因为要解析html,所以只装置了解析htmlplugin

    plugins: [
      new HtmlWebpackPlugin({filename: path.resolve(__dirname, './dist/[name].html'),
          template: path.resolve(__dirname, './src/index.html'),
          title: 'webpack.dev.config',
      })
    ],

    咱们比照一下根底配置,会发现 开发环境配置跟根底配置简直没差异,只是多应用了 devServer 配置项,来开启本地服务器调试:

// webpack.dev.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
+   mode: 'development',
+   devtool: 'inline-cheap-module-source-map',
    entry: {index: './src/index.js'},
    output: {path: path.resolve(__dirname, './dist'),
        filename: '[name]-[chunkhash:5].js',
    },
    module: {
        rules: [
            {test: /.(css|less)$/, 
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            },
            {test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset',
                parser: {
                    dataUrlCondition: {maxSize: 1024 * 3 // When the image size is < 3kb it will be converted to base64}
                },
                generator: {filename: '[name]-[contenthash:5][ext][query]' // Set the name of the output file
                }
            },
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {loader: 'babel-loader'}
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({filename: path.resolve(__dirname, './dist/[name].html'),
            template: path.resolve(__dirname, './src/index.html'),
            title: 'webpack.dev.config',
        })
    ],
+   devServer: {
+       static: {+           directory: path.join(__dirname, 'static'),
+       },
+   }
}

devServer

还记得咱们之前的案例,是怎么运行咱们的代码的吗?咱们都是打包完当前,用自带的编辑器(vscode)运行查看后果的。要是咱们平时开发是这么低效的话,那预计我的项目不必上线了。

因而 webpack 提供了一个非常人性化的配置项——devServer

想应用这个配置项,咱们须要先 npm i webpack-dev-server -D 装置 webpack-dev-server 依赖

从这么语义化的名字就晓得,它必定是开发环境下,能够提供某种服务的配置。

这个服务就是,这将会开启一个本地服务,将咱们配置的webpack,实时编译,保留在内存中,这样能够不便调试咱们的代码,这很好的满足了咱们本地开发须要高效的目标。

因而这个配置项,只用于咱们开发环境配置

devServer.static

文档解释:通知服务器从哪里提供内容。只有在你心愿提供动态文件时才须要这样做

谬误了解

devServe配置项,其实文档曾经写的挺具体了,这里讲一个可能容易混同的配置项——devServe.static

很多人应用webpack,都是复制粘贴,所以常常会看到上面这种配置:

output: {path: path.resolve(__dirname, './dist'),
}
devServer: {
    static: {directory: path.join(__dirname, 'dist'),
    }
}

因为咱们设置的打包后输入的文件夹个别都是 distdevServe.static 配置项指定要提供的动态文件目录也是 dist。所以,咱们自然而然会认为,此时webpack 开启的本地服务器拜访的内容就是 dist 文件夹外面的内容。

因而,咱们会得出谬误的论断:devServe.static的作用就是,设置 webpack 开启的本地服务器时,拜访的目录。

然而,咱们能够看看上文的 dev.config.js,咱们设置打包后输入的文件夹名称是 distdevServe.static 设置的目录是 static。如果依照咱们上文谬误的了解,因为两个文件夹设置不同,此时咱们服务器应该是404 或者空白页面才对,然而咱们仍旧能够跑起咱们的服务。

这阐明 devServe.static 的作用,并不是设置 webpack 开启的本地服务器时,拜访打包输入文件夹的目录。

正确理解

剖析

咱们持续看 learn-08 这个案例(static文件夹外面寄存了 logo.png 图片)。

咱们之前想在 js 外面援用相干图片,咱们个别会这么做:

// index.js
const img = new Image();
img.src = require('Your image path');

咱们个别是将图片 依据相对路径 require 进来,此时图片相当于是一个模块(Module),因而这样图片会通过 webpack 编译打包(增加 hash 或者转成base64),最初写入到咱们设置的最终目录(output.path)。

然而当咱们设置了:

devServer: {
    static: {directory: path.join(__dirname, 'static'),
    }
}

开启本地服务器后,会有这一句提醒:

Content not from webpack is served from ‘your path/static’ directory

首先,这阐明咱们设置的 static 这个目录,是不会通过 webpack 解决打包的,所以在这个文件夹外面的资源,是不会被 webpack 解析编译的,因而它也不会加上 hash 或转成base64

咱们再来看看 learn-08 的 index.js 是如何应用 static 里的资源的:

// index.js
loadImage('./logo.png').then(img => {console.log('I am from index.js');
    img.width = 120;
    document.querySelector('#js_content .img_content').append(img);
});

咱们会看到,咱们是间接应用 ./ 的形式引入图片,阐明 webpack 开启的本地服务器,会将咱们设置的 static 的目录内容 映射到根目录 下。

用过 vue-cli 的同学应该能很好领会到,这其实就是 vue-cli 外面 public 文件夹的性能

咱们能够用以下形式拜访设置的 devServer.static.directory 文件夹里的内容:

  • 个别状况下 devServer.static.directory 会被映射到根目录,所以咱们用 http://[devServer.host]:[devServer.port]/[devServer.static.directory] 拜访
  • 如果想扭转拜访的门路,能够减少 devServer.static.publicPath 配置。此时能够用 http://[devServer.host]:[devServer.port]/[devServer.static.publicPath]/[devServer.static.directory] 拜访

总结

通过下面的剖析解说,咱们能够得出对 devServer.static 正确的了解应该是:

  • 它是设置一个寄存,不通过 webpack 编译的动态资源目录(咱们能够例如图片,第三方资源等),所以它不会被加上 hash 或者被转成base64;它是一个目录
  • 开启 webpack 本地服务器时,它个别会被映射到咱们的我的项目的根目录下(能够通过 devServe.static.publicPath 批改拜访目录)
  • 因为它不通过 webpack 编译打包,所以,咱们最初个别会用 copy-webpack-plugin,将devServer.static.directory 复制到 output.path 根目录下
  • 它的性能就很像是 vue-cli 外面的 public 文件夹,咱们开发的时候,能够通过 ./ 或者 ../ 拜访到那个资源(具体看目录关系)

外围

好,通过上面对开发环境配置跟 devServer 的解说,咱们能够晓得:

  • 开发环境配置所有从简,所以 imgjs 等资源会间接映射在根目录下(css被插入到 <head /> 里了)
  • 开发环境 webpack 开启本地服务器后,也会将 devServer.static.directory 映射在根目录下

所以运行开发环境配置后,咱们的构造目录大抵如下:

dist
├── ecj-cli-b6fa8.png
├── index-c466b.js
├── index.html
└── logo.png

配置因人而异,最重要的是,咱们配置完开发环境,生产环境后,对编译打包输入内容,目录,脑海中有一个很好地构造意识,这是十分重要的

这个目录构造也请大家牢记,前面的文章会用到

咱们能够通过以下办法查看开发环境的构造目录:

  • devServer.devMiddleware.writeToDisk: true
  • http://[devServer.host]:[devServer.port]/webpack-dev-server
  • 谷歌浏览器F12 -> Sources

最初

  • 本篇文章学习了开发环境如何配置,下篇文章将会解说配置生产环境前一些筹备,让后续咱们更好的学习生产环境配置
  • 感兴趣的同学,能够关注一下这个 👉 专栏
  • 文章波及到的案例曾经上传到 github,真的欢送 starfork学习

最初的最初,如果大家感觉文章有帮忙到,创作不易,还请大家多点赞转发;如果有异同点,欢送评论探讨。

退出移动版