前端打包构建之-webpack篇

463 阅读6分钟

第一章 构建工具发展与webpack构建

简介:webpack是一个现代 JavaScript 应用程序的静态模块打包工具。

vue-cli 与webpack

  • 基`webpack构建,并带有合理的默认配置;
  • 可以通过项目内的配置文件进行配置;
  • 可以通过插件进行扩展。 CLI 服务是构建于webpack和webpack-dev-server 之上的。它包含了:
  • 加载其它 CLI 插件的核心服务;
  • 一个针对绝大部分应用优化过的内部的 webpack 配置;
  • 项目内部的 vue-cli-service 命令,提供 serve、build 和 inspect命令。

react Create React App 与 webpack

Create React App是FaceBook的React团队官方出的一个构建React单页面应用的脚手架工具。它本身集成了Webpack,并配置了一系列内置的loader和默认的npm的脚本,可以很轻松的实现零配置就可以快速开发React的应用。

npm install -g create-react-app   //安装
npx create-react-app my-app       //构建
cd my-app
npm start

angular-cli 与webpack

  • angular-cli 的底层打包基于webpack,cli上层对 webpack 配置进行了一层封装。
  • ng eject:导出 angular 项目的 webpack 配置(webpack.config.js),2.x以上不支持。
  • 最新:Angular CLI: 12.0.1。

前端构建演变之路

为什么需要构建工具?

  • 转换ES6语法
  • 转换JSX
  • CSS前缀补全/预处理器
  • 压缩混淆
  • 图片压缩
journey
title 前端构建演变之路
ant+yuicompressor:2: 初期
grunt: 3: 
fis3/gulp: 4: 
rollup/webpack/parcel: 5: 

微信图片_20211220010200.jpg 初期前端编写-切图,编写css,编写html,编写js,未做代码混淆,代码逻辑暴露。 Ant+YUI:主要压缩css/js(yuicompressor-2.4.8.jar

Grunt:JavaScript 任务运行器,将整个构建过程分为一个一个的任务,比如解析html,解析css,压缩图片,本地磁盘IO操作,打包速度慢;

Gulp:同grunt,任务打包器;

Fis3:基于文件对象进行构建,(百度)不在维护;

rollup:JavaScript 模块打包器,主要打包js;

parcel:(号称)零配置,场景受限与零配置的代价;

vite:下一代的构建工具,vue的现代标配(黑马);

初识webpack

webpack 社区生态丰富、配置灵活、功能强大;

环境搭建

mkdir webpack-demo
cd webpack-demo
npm init -y  //yes
npm install webpack webpack-cli --save-dev  //不推荐全局安装
npm info webpack   //查看webpack安装信息

webpack基础配置

Webpack默认配置文件 webpack.config.js
Webpack --config 指定配置文件
webpack.dev.config.js
webpack.prod.config.js
// webpack.config.js
'use strict'
const path = require('path');
module.exports = {
  mode: "production",
  entry: "./src/index.js",
  output: {
    path: path.join(__dirname, "dist"),
    filename: 'bundle.js',
    clean: true
  },
  module: {
    rules: []
  },
  //插件配置
  plugins: []
};

webpack打包构建

// 打包命令
./node_modules/.bin/webpack
npm run build      //(package.json配置参数--"build": "webpack")
npx webpack 
npx webpack --watch  //实时监听文件变化

注:npm 从5.2版开始,增加了 npx 命令,我们可以在命令行管理操作npm依赖;
截止目前:npm版本:6.14.12

第二章webpack基础用法

当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图会映射项目所需的每个模块,并生成一个或多个 bundle。

入口(entry)

entey用来指定webpack的打包入口,即依赖图的入口;

用法

// 单入口:字符串
entry:”./src/index.js// 多入口:对象
entry:{
   entry1: './src/index.js',
   entry2: './src/search.js',
}                       

输出(output)

output用来告诉webpack如何将编译后的文件输出到磁盘。

module.exports = {
  output: {
    // path: path.resolve(__dirname, "dist"), //绝对路径
    path: path.join(__dirname, "dist"),       //相对路径
    filename: 'bundle.js',    //单入口
    // filename: '[name].js'  //多入口:通过占位符确保文件名称的唯一
    clean: true, // 在生成文件之前清空 output 目录
  },

loader

wepack开箱即用:只支持jsjson 两种文件类型,通过loader去支持其他文件类型,并把他们转化成有效的模块,添加到依赖图;

loader本身是一个函数,接受源文件为参数,返回转换结果;

常见的loader

babel-loader:  //es转换
babel的配置文件: .babelrc
{
  "presets":[],
  "plugins":[]
}
style-loader   //将css-loader打包好的css代码以<style>标签的形式插入到html文件中。
css-loader:   //支持.css文件的加载和解析
less-loader:  // 转css
sass-loader:  //...
ts-loader:    //ts转换
gzip-loader: //gzip
//webpack5使用四种新增的资源模块(Asset Modules)替代了一下loader的功能:
raw-loader  //将文件导入为字符串
url-loader  //将文件作为 data URI 内联到 bundle 中
file-loader //将文件发送到输出目录 -(图片、字体) 

loader的用法

  • test-指定匹配规则;
  • use-指定使用的loader名称;
module.exports = {
  rules: [
    {
       test: /\.(png|jpg|gif)$/,
       use: {
         loader: 'file-loader',
         options: {},
     }, 
     {
        test: '/\.css$/',
        use: [
         {loader: 'style-loader'},
         {loader: 'css-loader'}]
      },
      {
         test: /\.css$/,
         use: ExtractTextPlugin.extract({
           fallback: "style-loader",
           use: "css-loader"
         })
       }
    ]
  }

使用loader加载css

// common.css
.content {
    padding: 10px;
}
.title {
    font-weight: 700;
    color: brown;
}
{
    test: /\.css$/,
    use: [{
      loader: 'style-loader'
    },
    {
       loader: 'css-loader'
    }]
 },   //或数组['style-loader','css-loader']
// index.js
import "./assets/css/common.css";
document.body.classList.add('hello')   //h5新增操作类名的方式

微信图片_20211222092012.png

plugin

插件用于bundle文件的优化,资源管理和环境变量的注入,作用于整个构建过程;比如删除上次构建目录(loader的增强)。

常见的plugin

BannerPlugin 该插件会在bundle.js顶部生成一个版权声明;
CommonsChunkPlugin 提取成公共js;
ExtractTextWebpackPlugin 独立css文件,可与css-loader配合使用;
HtmlWebpackPlugin  dist下生成一个html并引入bundle.js脚本;   
CleanWebpackPlugin  构建之前的清空操作,同output clean参数;

plugin用法

npm install --save-dev html-webpack-plugin  // 插件安装
// package.json
"devDependencies": {
    "clean-webpack-plugin": "^4.0.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "html-webpack-plugin": "^5.5.0",
 }
//放到plgins数组里面
const webpack = require('webpack');   //访问内置的插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过npm安装
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); //对象解构
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', //输出文件名
      template: './index.html',
      inject: 'body',  // true||'head'||'body'||false--在body生成script标签
    }),
    new CleanWebpackPlugin(),
    new webpack.BannerPlugin('版权所有!'),
  ]
};

mode

模式(mode)

mode用来指定当前的构建环境是:production、development还是none(string),设置mode可以使用webpack内置的函数,默认值为production

微信图片_20211219223822.png

资源模块

webpack5资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader,即打包其他的资源文件,比如字体、图像资源等。

1. Resource资源

asset/resource 将资源分割为单独的文件,并导出url,就是之前的 file-loader的功能。
打包图片时默认生成扩展名,打包图片资源到dist目录下,可通过手动配置生成到指定文件夹下面。

output: {
    path: path.join(__dirname, "dist"),
    filename: 'bundle.js',
    clean: true, 
    assetModuleFilename: 'imagess/[hash][ext][query]',  //将资源发送到指定目录---方法1***
},
module: {
    rules: [
      {
        test: /\.png$/,
        type:'asset/resource',
        generator: {
          filename: 'static/[hash][ext][query]'   //方法2***
        }
      }
    ]
}
import mainImage from './images/profile_photo_3.png';

const img = document.createElement('img')
img.src = mainImage; // '/dist/4942ae72e92486229f6a.png'
document.body.appendChild(img); //页面添加元素

2.inline资源

asset/inline 将资源导出为dataURL(url(data:))的形式,不会在dist目录下生成文件,之前的 url-loader的功能;

module: {
    rules: [
      {
        test: /.svg$/,
        type:'asset/inline'
      }
    ]
}
import mainsvg from './images/test.svg';

const svg = document.createElement('img')
svg.src = mainsvg;
document.body.appendChild(svg);
// 效果呈现
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSI+DQogICA8Y2lyY2xlIGN4PSIxMDAiIGN5PSI1MCIgcj0iNDAiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0icmVkIj48L2NpcmNsZT4NCjwvc3ZnPg==">

3.source资源

asset/source 将资源导出为源码(source code),之前的 raw-loader 功能;

module: {
    rules: [
      {
        test: /.txt$/,
        type:'asset/source'
      }
    ]
}
// example.txt : webpack 前端构建
import exampleText from './example.txt';
const block = document.createElement('div')
block.textContent = exampleText; 
document.body.appendChild(block);
//打包到bundle.js:module.exports = "webpack前端构建";

4.URL资源

asset 自动选择导出为单独文件(asset/resource)或者 dataURL(asset/inline)形式(默认为8KB),之前有url-loader设置asset size limit 限制实现。

{
    test: /\.jpg$/,
    type: 'asset',
    parser: {
      dataUrlCondition: {
         maxSize: 8 * 1024 // 8kb 临界值设置
      }
   }
 }
const logo = new URL('./logo.svg', import.meta.url);

使用webpack-dev-server实现自动刷新

安装:npm install webpack-dev-server --save-dev
运行:node_modules/.bin/webpack-dev-server
      npx webpack-dev-server --open   // --open 自动打开浏览器

webpack-dev-server就是一个小型的静态文件服务器

webpack-dev-server有两种模式支持自动刷新——iframe模式和inline模式

// 服务器配置
module.exports = {
  devServer: {
     port: '8888',
     static: './dist'
   }
}