【Webpack 开发环境配置】总结学习如何打包样式资源、html资源、图片资源和其他资源?devServer是什么,如何配置?

webpack系列文章:

webpack.config.js

webpack 开箱即用,可以无需使用任何配置文件。然而,webpack 会假定项目的入口起点为 src/index.js,然后会在 dist/main.js 输出结果,并且在生产环境开启压缩和优化

通常你的项目还需要继续扩展此能力,为此你可以在项目根目录下创建一个 webpack.config.js 文件,然后 webpack 会自动使用它。

webpack.config.js是webpack的配置文件。 作用是:指示 webpack 干哪些活(当你运行 webpack 指令时,会加载里面的配置)

所有构建工具都是基于nodejs平台运行的~模块化默认采用commonjs。

下面开始介绍webpack的这个配置文件

创建配置文件

1. 创建文件 webpack.config.js

2. 配置内容如下

const { resolve } = require('path'); // node 内置核心模块,用来处理路径问题。

module.exports = {
	entry: './src/js/index.js', // 入口文件
	output: { // 输出配置
		filename: './built.js', // 输出文件名
		path: resolve(__dirname, 'build/js') // 输出文件路径配置
	},
	mode: 'development' //开发环境
};

如何打包样式资源以及loader执行顺序是什么

打包 CSS 资源

1. 下载安装 loader 包

npm i css-loader style-loader less-loader less -D

2. 修改配置文件

/*
  webpack.config.js  webpack的配置文件
    作用: 指示 webpack 干哪些活(当你运行 webpack 指令时,会加载里面的配置)

    所有构建工具都是基于nodejs平台运行的~模块化默认采用commonjs。
*/

// resolve用来拼接绝对路径的方法
const { resolve } = require('path');

module.exports = {
  // webpack配置
  // 入口起点
  entry: './src/index.js',
  // 输出
  output: {
    // 输出文件名
    filename: 'built.js',
    // 输出路径
    // __dirname nodejs的变量,代表当前文件的目录绝对路径
    path: resolve(__dirname, 'build')
  },
  // loader的配置
  module: {
    rules: [
      // 详细loader配置
      // 不同文件必须配置不同loader处理
      {
        // 匹配哪些文件
        test: /\.css$/,
        // 使用哪些loader进行处理
        use: [
          // use数组中loader执行顺序:从右到左,从下到上 依次执行
          // 创建style标签,将js中的样式资源插入进行,添加到head中生效
          'style-loader',
          // 将css文件变成commonjs模块加载js中,里面内容是样式字符串
          'css-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          // 将less文件编译成css文件
          // 需要下载 less-loader和less
          'less-loader'
        ]
      }
    ]
  },
  // plugins的配置
  plugins: [
    // 详细plugins的配置
  ],
  // 模式
  mode: 'development', // 开发模式
  // mode: 'production'
}

模块loader可以链式调用。链中的每个loader都将对资源进行转换。链会逆序执行。第一个loader将其结果(被转换后的资源)传递给下一个loader,依此类推。最后,webpack期望链中的最后的loader 返回 JavaScript。

应保证 loader 的先后顺序:‘style-loader’ 在前,而 ‘css-loader’ 在后。如果不遵守此约定,webpack 可能会抛出错误。

不同文件必须配置不同loader处理

css文件要用style-loadercss-loader

less文件要用less-loaderstyle-loadercss-loader

具体这三个loder的作用见上面代码注释。

loader执行顺序(非常重要,切记!!!):

use数组中loader执行顺序:从右到左,从下到上 依次执行

其实所谓的从下到上就是把数组里的每个元素换行展示了,本质还是数组从右至左。

如何打包html资源

打包html资源需要用到html-webpack-plugin这个插件,下载安装 plugin 包

npm install --save-dev html-webpack-plugin

实例文件目录:
在这里插入图片描述
loader使用的一个区别是,插件plugin下载后需要引入后才能使用:

// 引入
const HtmlWebpackPlugin = require('html-webpack-plugin');

默认配置:

/*
  loader: 1. 下载   2. 使用(配置loader)
  plugins: 1. 下载  2. 引入  3. 使用
*/
const { resolve } = require('path');
// 引入
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      // loader的配置
    ]
  },
  plugins: [
    // plugins的配置
    // html-webpack-plugin
    // 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
    new HtmlWebpackPlugin()
  ],
  mode: 'development'
};

html-webpack-plugin插件的功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
在这里插入图片描述
实际开发中我们的需求:需要有结构的HTML文件

我们可以通过对HtmlWebpackPlugin添加配置选项template,添加目标html文件的路径即可,具体配置如下:

/*
  loader: 1. 下载   2. 使用(配置loader)
  plugins: 1. 下载  2. 引入  3. 使用
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      // loader的配置
    ]
  },
  plugins: [
    // plugins的配置
    // html-webpack-plugin
    // 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
    // 需求:需要有结构的HTML文件
    new HtmlWebpackPlugin({
      // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

目标html文件:
在这里插入图片描述
打包出来的文件:
在这里插入图片描述

html-webpack-plugin插件设置template配置属性的功能:复制 ‘./src/index.html’ 文件,并自动引入打包输出的所有资源(JS/CSS)

如何打包图片资源

为什么需要对webpack做打包图片的配置?我们先看一个在样式中引入图片(background-image)的实例

实例目录结构如下:
在这里插入图片描述
index.html:
在这里插入图片描述

index.js:
在这里插入图片描述
index.less:
在这里插入图片描述
如果我们不对图片资源做配置的话,基础的webpack.config.js配置如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        // 要使用多个loader处理用use
        use: ['style-loader', 'css-loader', 'less-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

对项目进行打包后,我们发现图片资源处理不了,在打包图片的时候是报错的:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以我们需要对图片进行单独的处理

我们使用url-loader来处理图片资源,这里需要下载url-loaderfile-loade两个loader:

npm i url-loader file-loade -D

url-loader有相应的优化配置属性limit,写在options里,

limit属性的作用:图片大小小于指定数值时,就会被base64处理

  • 优点:减少请求数量(减轻服务器压力)
  • 缺点:图片体积会更大(文件请求速度更慢)

配置如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        // 要使用多个loader处理用use
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
        // 问题:默认处理不了html中img图片
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        // 使用一个loader
        // 下载 url-loader file-loader
        loader: 'url-loader',
        options: {
          // 图片大小小于8kb,就会被base64处理
          // 优点: 减少请求数量(减轻服务器压力)
          // 缺点:图片体积会更大(文件请求速度更慢)
          limit: 8 * 1024
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

配置完成后再次打包运行:
在这里插入图片描述
图片资源没有报错。

这里我们备注一下上面代码里我们用到的三张图片资源:

angular.jpg,12kb大小:
在这里插入图片描述
react.png,74kb大小:
在这里插入图片描述
vue.jpg,4kb大小:
在这里插入图片描述
再来看一下输出的资源:
在这里插入图片描述
我们发现打包后的资源输出了两张图片,一张74kb,一张12kb,但我们实际上引入了三张图片,还有以这样图片去哪里呢?

我们看build:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们发现vue.jpg经过了base64处理,变成了一个非常长的编码字符串,变成了字符串的形式,而不会输出成一张图片,所以我们输出的结果就少了一张图片。这正是前面url-loader做优化配置属性limit后的效果。

我们打开build文件下的index.html文件验证一下效果:
在这里插入图片描述
三张图片正常显示

我们检查一下html结构,可以发现box1盒子背景图片(vue.jpg)的url是一个base64的地址:
在这里插入图片描述
到这里我们处理了样式里的图片资源,只是这样还不够,因为除了在样式中引入图片以外,我们还可能在html中通过<img>标签的方式引入图片:<img src="./angular.jpg" alt="angular">
在这里插入图片描述
在html中通过<img>标签的方式引入图片后,在原有的配置中我们再打包一次,发现没有报错,输出的结果和之前一样,打开build下的index.html:
在这里插入图片描述
img的路径还是src="./angular.jpg"./是相对路径,但是相对路径下没有angular.jpg这张图片:
在这里插入图片描述
我们打开build下的index.html,发现<img src="./angular.jpg" alt="angular">这张图片是找不到的:
在这里插入图片描述
这是因为上面url-loader的配置有一个问题:默认处理不了html中img图片

这里我们还要再加一个loader:html-loader作用是:处理html文件的img图片(负责引入img,从而能被url-loader进行处理)

下载html-loader:

npm i html-loader -D

配置:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        // 要使用多个loader处理用use
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
        // 问题:默认处理不了html中img图片
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        // 使用一个loader
        // 下载 url-loader file-loader
        loader: 'url-loader',
        options: {
          // 图片大小小于8kb,就会被base64处理
          // 优点: 减少请求数量(减轻服务器压力)
          // 缺点:图片体积会更大(文件请求速度更慢)
          limit: 8 * 1024
        }
      },
      {
        test: /\.html$/,
        // 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
        loader: 'html-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

上面的配置打包后发现还是没有报错,但是build下的index.html文件里img的src变成了[object Module]
在这里插入图片描述
这是为什么呢?

这是 因为url-loader默认使用es6模块化解析,而html-loader引入图片是common.jsurl-loader以es6模块去解析common.js模块,解析不了。

解决方法:关闭url-loader的es6模块化,使用commonjs解析

{
  // 问题:默认处理不了html中img图片
  // 处理图片资源
  test: /\.(jpg|png|gif)$/,
  // 使用一个loader
  // 下载 url-loader file-loader
  loader: 'url-loader',
  options: {
    // 图片大小小于8kb,就会被base64处理
    // 优点: 减少请求数量(减轻服务器压力)
    // 缺点:图片体积会更大(文件请求速度更慢)
    limit: 8 * 1024,
    // 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
    // 解析时会出问题:[object Module]
    // 解决:关闭url-loader的es6模块化,使用commonjs解析
    esModule: false
  }
},

关闭url-loader的es6模块化,再次打包,没有报错

查看build下的index.html文件
在这里插入图片描述
img的src变成[object Module]的问题已经解决,变成了完整的绝对路径,上面的长字符串是根据图片内容生成的唯一hash值。

打开build下的index.html文件,html里的图片显示正常:
在这里插入图片描述
我们发现打包后图片的名字有点长,这是根据图片内容生成的唯一hash值:
在这里插入图片描述
不想让图片名字这么长可以通过url-loader里的name属性来给图片进行重命名:name: '[hash:10].[ext]'

  • [hash:10]取图片的hash的前10位
  • [ext]取文件原来扩展名

对图片资源最终的配置如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        // 要使用多个loader处理用use
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
        // 问题:默认处理不了html中img图片
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        // 使用一个loader
        // 下载 url-loader file-loader
        loader: 'url-loader',
        options: {
          // 图片大小小于8kb,就会被base64处理
          // 优点: 减少请求数量(减轻服务器压力)
          // 缺点:图片体积会更大(文件请求速度更慢)
          limit: 8 * 1024,
          // 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
          // 解析时会出问题:[object Module]
          // 解决:关闭url-loader的es6模块化,使用commonjs解析
          esModule: false,
          // 给图片进行重命名
          // [hash:10]取图片的hash的前10位
          // [ext]取文件原来扩展名
          name: '[hash:10].[ext]'
        }
      },
      {
        test: /\.html$/,
        // 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
        loader: 'html-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

打包后的图片名称已经变成取图片的hash的前10位
在这里插入图片描述
另外我们还可以发现webpack打包的一个优势:

上面的例子中html里引用了一次angular.jpg,在样式文件里也引用了一次angular.jpg,但打包之后其实只生成了一张angular.jpg的图片文件

所以在这里就是当webpack在解析的时候发现我们使用了同一个文件,它不会重复打包,它只会输出一次,这也是webpack的一个优势,它不会重复打包某一个文件。

如何打包其他资源

什么是其他资源呢?比如说字体图标icon

字体图标的特点就是我们不需要做任何处理,只需要原封不动的输出出去就ok了,这就是其他资源,不需要做优化,也不需要做压缩啊等等,这类资源统一归类于其他资源。

我们先下载一个字体图标,这里使用iconfont图标,随便选择一个,直接点击下载代码
在这里插入图片描述
下载完之后解压一下,这里包含了字体图标的所有配置
在这里插入图片描述
我们这里使用font-class 引用
在这里插入图片描述
我们新建文件夹,src/index.html,使用字体图标看一看效果
在这里插入图片描述
在这里插入图片描述
再写一个入口js文件,index.js,作用就是负责引入字体图标样式文件
在这里插入图片描述
iconfont.css文件里又引用了.eot.woffttf.svg资源,我们也需要放入项目中,具体看前面的实例项目文件目录
在这里插入图片描述
打包其他资源我们可以使用exclude排除已经处理过或者不需要处理的资源,然后使用file-loader对其他资源进行处理,一个小的优化就是可以对打包后的文件名称做一个缩短优化

具体配置:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      // 打包其他资源(除了html/js/css资源以外的资源)
      {
        // 排除css/js/html资源
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]'
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

打包运行项目,字体图标显示正常
sa

如何配置devServer

webpack-dev-server具有实时重新加载 (live reloading) 的功能。用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)

特点:只会在内存中编译打包,不会有任何输出

启动devServer指令为npx webpack-dev-server

webpack devServer启动gzip压缩:compress: true

配置如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      // 打包其他资源(除了html/js/css资源以外的资源)
      {
        // 排除css/js/html资源
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]'
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development',

  // 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
  // 特点:只会在内存中编译打包,不会有任何输出
  // 启动devServer指令为:npx webpack-dev-server
  devServer: {
    // 项目构建后路径
    contentBase: resolve(__dirname, 'build'),
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 3000,
    // 自动打开浏览器
    open: true
  }
};

配置好devServer,启动devServer,打开浏览器,输入:localhos:3000,这就是我们使用devServer搭建的服务器,这个服务器启动的项目。

开发环境配置总结——一个完整的开发环境配置

除了之前的配置,我们还要做一些处理,之前编写的实例目录有点乱
在这里插入图片描述
我们划分一下目录
在这里插入图片描述

把原来的路径修改好后,输入命令webpack打包项目,看一下输出结果:
在这里插入图片描述
我们发现所有的资源都输出到一块了,没有任何的差别

如果希望打包后的资源和原来的结构一样的,可以一个一个调

首先让先js文件输出到js的目录下,要修改outputfilename属性,在built.js前加js/

  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },

重新构建一下项目,可以发现build下面就多了一个js目录
在这里插入图片描述
图片资源修改构建路径要在url-loader中添加outputPath配置属性:outputPath: 'imgs'

 {
   // 处理图片资源
   test: /\.(jpg|png|gif)$/,
   loader: 'url-loader',
   options: {
     limit: 8 * 1024,
     name: '[hash:10].[ext]',
     // 关闭es6模块化
     esModule: false,
     outputPath: 'imgs'
   }
 },

这样图片资源就会构建在build下面的imgs文件夹下
在这里插入图片描述
其他资源修改构建路径也是添加outputPath配置属性:outputPath: 'media'

  {
    // 处理其他资源
    exclude: /\.(html|js|css|less|jpg|png|gif)/,
    loader: 'file-loader',
    options: {
      name: '[hash:10].[ext]',
      outputPath: 'media'
    }

在这里插入图片描述
把build目录删掉,重新打包一次,就可以看到清晰的结构
在这里插入图片描述
有人可能会问,为什么构建后的资源没有看到之前写的css文件?这是因为css-loader把css文件打包到js当中了(复习环节),它是跟js文件融为一体的,所以没有被单独打包出去

  {
     // 匹配哪些文件
     test: /\.css$/,
     // 使用哪些loader进行处理
     use: [
       // use数组中loader执行顺序:从右到左,从下到上 依次执行
       // 创建style标签,将js中的样式资源插入进行,添加到head中生效
       'style-loader',
       // 将css文件变成commonjs模块加载js中,里面内容是样式字符串
       'css-loader'
     ]
   },

在这里插入图片描述
完整的开发环境配置:

/*
  开发环境配置:能让代码运行
    运行项目指令:
      webpack 会将打包结果输出出去
      npx webpack-dev-server 只会在内存中编译打包,没有输出
*/

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      // loader的配置
      {
        // 处理less资源
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
        // 处理css资源
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',
        options: {
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          // 关闭es6模块化
          esModule: false,
          outputPath: 'imgs'
        }
      },
      {
        // 处理html中img资源
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
        // 处理其他资源
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]',
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    // plugins的配置
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true
  }
};

结尾

我是圆圆,如果我的文章对你的学习成长有所帮助,欢迎 点 赞 👍 支持,您的 点 赞 👍 支持是我进行创作和分享的动力!

如果有问题可以留言评论或者私信我,我都会一一解答~笔芯🤞

参考

  • https://www.bilibili.com/video/BV1e7411j7T5?p=6
  • https://webpack.docschina.org/concepts/
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值