前端工程化之webpack学习记录

219 阅读3分钟

本文是本人正式开始学习webpack的记录文档, 时间:2020-05-16, webpack版本:"webpack": "^4.43.0", "webpack-cli": "^3.3.11"

为什么需要构建工具

转换ES6语法 转换JSX CSS前缀补全/预处理器 压缩混淆 图片压缩 ... 前端三大框架Vue.js React.js Angular.js的学习与使用都离不开webpack。 webpack是拓宽前端技术栈必不可少的一步。

初识webpack

webpack默认配置文件:webpack.config.js

可以通过webpack --config指定配置文件,比如区分开发环境与生产环境。

webpack配置组成

module.exports = {
  entry:"./src/index.js",  //........................打包的入口文件
  output:"./dist/main.js", //........................打包的输出
  mode:"production",       //........................环境
  module:{                 //........................Loader配置
    rules:[
      {test:/\.txt$/,use:"raw-loader"}
    ]
  },
  plugins:[                //........................插件配置
    new HtmlwebpackPlugin({
      template:"./src/index.html"
    })
  ]
}

零配置webpack包含内容

不用编写webpack.config.js时webpack默认配置

entry:"./src/index.js",
output:"./dist/main.js"

环境搭建:安装webpack

默认已安装node,我的node版本:v12.13.0

  1. 创建一个文件夹 npm init -y初始化一个package.json文件
  2. npm install webpack webpack-cli --save-dev,进行局部安装。
  3. 一个基本的例子: webpack.config.js
const path = require("path");
module.exports = {
  entry:"./src/index.js",
  output:{
    path:path.join(__dirname,'dist'),
    filename:"main.js"
  }
  mode:"production"
}

运行:./node_modules/.bin/webpack

基本的例子

  1. 通过npm script运行webpack 在package.json文件中
"scripts":{
  "build":"webpack"
}

之后直接运行npm run build.

webpack基础用法

webpack核心概念之Entry

Entry用来指定webpack打包的入口

单入口:entry是一个字符串,适用单页应用。

module.exports = {
  entry:"./src/index.js"
}

多入口:entry是一个对象,适用于多页应用。

module.exports = {
  entry:{
    index:"./src/index.js",
    admin:"./src/admin.js"
  }
}

webpack核心概念之Output

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

Output用法:单入口配置

module.exports = {
  entry:"./src/index.js",
  output:{
    filename:"bundle.js",   //............打包后文件名称
    path:__dirname+"/dist"  //............打包后文件存放目录
  }
}

Output用法:多入口配置

module.exports = {
  entry:{
    index:"./src/index.js",
    admin:"./src/admin.js"
  },
  output:{
    filename:"[name].js", //.........通过占位符确保文件名称的唯一
    path:__dirname+"/dist"
  }
}

不管一个入口还是多个入口,只有一个output,当有多个入口时,使用占位符name表示打包输出后的文件名称。

webpack核心概念之Loaders

webpack开箱即用只支持JS和JSON两种类型文件,通过Loaders去支持其他文件类型并且把他们转化成有效的模块。并且可以添加到依赖图中。

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

常见的Loaders有哪些?

名称 描述
babel_loader 转换ES6、ES7等JS新特性语法
css-loader 支持.css文件的加载和解析
less-loader 将less文件转换成css
ts-loader 将TS转换成JS
file-loader 进行图片、字体等的打包
raw-loader 将文件以字符串的形式导入
thread-loader 多进程打包JS和CSS

Loaders的用法

module.exports = {
  module:{
    rules:[
      {test:/\.txt$/,use:"raw-loader"} // ...    test指定匹配规则 use指定使用的loader名称
    ]
  }
}

loader需要放到根节点下面的module中,module是一个对象,对象中有一个数组rules,将所有loader都放到rules数组中即可。每一个loader的使用都需要使用test去指定匹配规则,使用use去指定使用的loader名称。loader还有一个参数是exclude,排除,排除掉某项,使其不参与匹配,比如node_modules包中的文件大多都是已经转换过的,无需再参加匹配转换,因此需要将其过滤掉以提高代码构建效率。

webpack核心概念之Plugins

插件用于bundle文件的优化,资源管理和环境变量注入。 作用于整个构建过程。 任何不能通过loader完成的任务可以使用plugin去完成。

名称 描述
CommonsChunkPlugin 将chunks相同的模块代码提取成公共js
CleanWebpackPlugin 清理构建目录
ExtractTextWebpackPlugin 将css从bundle文件中提取出来成为一个独立的css文件
CopyWebpackPlugin 将文件或文件夹拷贝到构建的输出目录
HtmlWebpackPlugin 创建html文件出承载输出的bundle
UglifyjsWebpackPlugin 压缩JS(webpack 4.x默认)
ZipWebpackPlugin 将打包出的资源生成一个zip包

Plugins的用法

const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
  plugins:[
    new HtmlWebpackPlugin({template:"./src/index.html"}) // ..... 放到plugins数组中
  ]
}

将插件放到plugins数组中,如有多个插件继续放入plugin数组中即可。

webpack核心概念之Mode

Mode用来指定当前的构建环境:production、development、还是none

设置mode可以自动触发webpack中的某些函数

Mode的内置函数功能

选项 描述
development 设置 process.env.NODE_ENV的值为development.
开启NameChunksPluginNameModulesPlugin.
production 设置process.env.NODE_ENV的值为production.
开启FlagDependencyUsagePlugin, FlagIncludeChunksPlugin
ModileConcatentationPluginNoEmitOnErrorsPlugin
OccurrenceOrderPluginSideEffectsFlagPluginTerserPlugin.
none 不开启任何优化选项

资源解析

ES6

使用babel-loader 需要使用babel的配置文件:.babelrc

安装: npm i @babel/core @babel/preset-env babel-loader -D

配置文件: 在项目根节点中创建.babelrc

{
  "presets":[
     "@babel/preset-env" 
  ]
}

webpack.config.js

const path = require("path");
module.exports = {
  entry:"./src/index.js",
  output:{
    path:path.join(__dirname,'dist'),
    filename:"bundle.js"
  },
  mode:"production",
  module:{
    rules:[
      {test:/\.js$/,use:"babel-loader",exclude:/node_modules/}
    ]
  }
}

解析React JSX

安装:npm i react react-dom @babel-preset-react -D

增加 React 的babel preset 配置

{
  "presets":[
     "@babel/preset-env" ,
     "@babel/preset-react"
  ]
}

测试: src/index.js

"use strict"
import React from 'react';
import ReactDOM from 'react-dom';
class Test extends React.Component{
    render(){
        return (
            <div className="text">
                Test 
            </div>
        )
    }
}
ReactDOM.render(
    <Test />,
    document.getElementById("root")
)

执行npm run build 打包,成功后在dist文件夹中新建一个index.html文件,通过script标签手动引入bundle.js,注意需要有id为root的元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="root">
        
    </div>
    <script src="./bundle.js"></script>
</body>
</html>

然后在网页中打开html文件预览。如果正常显示文本Test那说明成功了。

解析CSS

css-loader 用于加载.css文件,并且转换成commonjs对象

style-loader将样式通过