webpack入门学习(一)

204 阅读8分钟

webpack

文档

官方网站:webpack.js.org/

中文网站:www.webpackjs.com/

1.webpack简介

webpack is a module bundler(模块打包工具)

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

Webpack是⼀一个打包模块化JavaScript的⼯具,它会从⼊口模块出发,识别出源码中的模块化导⼊语句,递归地找出⼊口⽂件的所有依赖,将⼊口和其所有的依赖打包到⼀个单独的⽂件中

是工程化、自动化思想在前端开发中的体现

2.安装webpack

  • 环境准备

node.js:nodejs.org/en/

版本参考官⽹发布的最新版本,可以提升webpack的打包速度

  • 全局安装(不推荐)

# 安装webpack V4+版本时,需要额外安装webpack-cli 
npm install webpack webpack-cli -g

# 检查版本
webpack -v

# 卸载
npm uninstall webpack webpack-cli -g

全局安装webpack,这会将你项目中的webpack锁定到指定版本,造成不同 的项目中因为webpack依赖不同版本⽽导致冲突,构建失败

  • 项目安装(推荐)

# 安装最新的稳定版本
npm i webpack webpack-cli -D

# 安装指定版本
npm i -D webpack@<version>

# 安装最新的体验版本 可能包含bug,不要⽤于生产环境 
npm i -D webpack@beta

  • 检查安装
webpack -v //command not found 默认在全局环境中查找


npx webpack -v// npx帮助我们在项目中的node_modules⾥里里查找webpack ./node_modules/.bin/webpack -v//到当前的node_modules模块⾥指定 webpack

3.启动webpack执行构建

1.webpack 默认配置

  • 默认入口模块
    • ./src/index.js
  • 默认输出
    • 名称 main.js
    • 路径是 './dist'
  • webpack 默认支持多种模块类型:比如CommonJS ESModule AMD
  • webpack默认支持js模块和json模块
  • webpack4⽀持零配置使⽤,但是很弱,稍微复杂些的场景都需要额外扩 展

2.准备执行构建

  • 新建src文件夹
  • 新建src/index.js, src/index.json, src/other.js
// index.js
const json = require("./index.json");//commonJS import { add } from "./other.js";//es module console.log(json, add(2, 3));

// index.json
{
    "name": "JSON"
}

// other.js
export function add(a, b) {
    return a + b
}

3.执行构建

# npx方式
npx webpack

# npm script
npm run test

修改package.json文件

"scripts": {
    "test": "webpack"
}

原理就是通过shell脚本在node_modules/.bin目录下创建一个软链接

4.构建成功

我们会发现目录下多出一个 dist 目录,里面有个 main.js ,这个文件是 一个可执行的JavaScript文件,里面包含webpackBootstrap启动函数

5.默认配置

// webpack.config.js

const path = require('path')

module.exports = {
    //! 必填  webpack 执行构建入口
    entry: './src/index.js',
    //! 出口
    output: {
        //! 将所有依赖的模块合并输出到main.js 
        filename: 'main.js',
        //! 输出文件的存放路径,必须是绝对路径
        path: path.resolve(__dirname, './dist')
    },
    module: {
        rules: [
            //! loader模块处理(执行顺序从下到上,从右到左)
            {
                test: /\.css$/,
                use: 'style-loader'
            }
        ]
    },
    plugins: [ //! 插件配置
        new HtmlWebpackPlugin()
    ]
}

4.webpack配置核心概念

webpack有默认的配置文件,叫 webpack.config.js ,我们可以对这个文件进行修改,进行个性化配置

  • 使用默认的配置文件:webpack.config.js
  • 不使用自定义配置文件:比如webpack.dev.js,可以通过 --config webapcK.dev.js来指定webpack使用哪个配置文件来执行构建

webpack.config.js配置基础结构

module.exports = {
    entry: './src/index.js', // 打包入口文件
    output: './dist'// 输出结构
    mode: 'production', // 打包环境
    module: {
        rules: [
            //! loader模块处理(执行顺序从下到上,从右到左)
            {
                test: /\.css$/,
                use: 'style-loader'
            }
        ]
    },
    plugins: [ //! 插件配置
        new HtmlWebpackPlugin()
    ]
}

1.entry

指定webpack打包入口文件:Webpack 执行构建的第一步将从 Entry 开始, 可抽象成输入

// 单入口
entry: {
    main: './src/index.js'  
}
// 相当于简写 
entry:"./src/index.js"

// 多入口 entry是个对象
entry: {
    index: './src/index.js',
    login: './src/login.js'
}

2.output

打包转换后的文件输出到磁盘位置:输出结果,在webpack经过一系列处理并得出最终想要的代码后输出结果

//! 出口
output: {
    //! 将所有依赖的模块合并输出到main.js 
    filename: 'main.js',
    //! 输出文件的存放路径,必须是绝对路径
    path: path.resolve(__dirname, './dist')
},
    
// 多入口的处理
output: {
    filename: '[name][chunkhash:8].js', // 利用占位符,文件名称不要重复
    path: path.resolve(__dirname, './dist') // 输出⽂文件到磁盘的⽬目录,必 须是绝对路路径 
}

3.mode

mode用来指定当前的构建环境

  • production(默认)
  • development
  • none

设置mode可以自动触发webpack内置的函数,达到优化的效果

选项 描述
development 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPluginNamedModulesPlugin
production 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPluginUglifyJsPlugin.

如果没有设置,webapck默认mode为 production。模式支持的值为

记住,只设置 NODE_ENV,则不会自动设置 mode。

开发阶段的开启会有利于热更新的处理,识别哪个模块变化

生产阶段的开启会有帮助模块压缩,处理副作⽤等一些功能

4.loader

模块解析,模块转换器,⽤于把模块原内容按照需求转换成新内容。

webpack是模块打包⼯工具,⽽模块不仅仅是js,还可以是css,图片或者其他 格式

但是webpack默认只知道如何处理js和JSON模块,那么其他格式的模块处理,和处理⽅式就需要loader了

常见的loader
style-loader
css-loader 
less-loader 
sass-loader 
ts-loader //将Ts转换成js 
babel-loader//转换ES6、7等js新特性语法 
file-loader//处理理图⽚片⼦子图 
eslint-loader 
vue-loader
...

5.module

模块,在 Webpack 里一切皆模块,一个模块对应着一个⽂文件。Webpack 会 从配置的 Entry 开始递归找出所有依赖的模块。

当webpack处理到不认识的模块时,需要在webpack中的module处进行配 置,当检测到是什么格式的模块,使⽤什么loader来处理。

module: {
        rules: [
            //! loader模块处理(执行顺序从下到上,从右到左)
            {
                test: /\.xxx$/,  // 指定匹配规则
                use: {
                    loader: 'xxx-loader' // 指定使用的loader
                }
            }
        ]
    },
        
  • 处理静态资源模块: file-loader

原理是把打包⼊口中识别出的资源模块,移动到输出目录,并且返回一 个地址名称

所以我们什什么时候⽤用file-loader呢?

场景:就是当我们需要模块,仅仅是从源代码挪移到打包目录,就可以 使⽤file-loader来处理,txt,svg,csv,excel,图⽚资源啦等等

// 记得先去安装对应loader
npm install file-loader -D

举个栗子

module: {
        rules: [
            //! loader模块处理(执行顺序从下到上,从右到左)
            {
                test: /\.(png|jpe?g|gif)$/,
                 // use使用⼀个loader可以用对象,字符串,两个loader需要用数组 
                use: [{
                    loader: 'file-loader',
                    //  options额外的配置,比如资源名称 
                    options: {
                        //  placeholder 占位符  [name]老资源模块的名称            
                        // [ext]老资源模块的后缀 
                        name: '[name]_[hash].[ext]',
                        // 打包后的存放位置
                        outputPath: 'images/'
                    }
                }]
            }
        ]
    },
        
 // index.js
import pic from './logo.jpg'

var img = new Image()
img.src = pic
img.classList.add('logo')

var root = document.getElementById("root"); 
root.append(img);
  • 处理字体(推荐iconfont)
// css
@font-face {
    font-family: webfont;
    font-display: swap;
    src: url('webfont.woff2') format('woff2')
}

body {
    background: red;
    font-family: 'webfont' !important;
}

// webpack.config.js
{
    test: /\.(eot|ttf|woff|woff2|svg)$/,
    use: 'file-loader'
}
  • url-loader file-loader加强版本

    url-loader内部使⽤了file-loader,所以可以处理file-loader所有的事情,但 是遇到jpg格式的模块,会把该图片转换成base64格式字符串,并打包 到js里。对小体积的图片比较合适,大图片不合适。

npm install url-loader -D

举个栗子

module: {
    rules: [
        {
                test: /\.(png|jpe?g|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name]_[hash].[ext]',
                        outputPath: 'images/',
                        // 小于2048,才换成base64
                        limit: 2048
                    }
                }
            }
    ]
}
  • 样式处理

css-loader分析css模块之间的关系,并合成一个css

style-loader会把css-loader生成的内容,以style挂载到页面的header部分

npm install style-loader css-loader -D
{
    test: /\.css$/,
    //! css-loader分析css模块之间的关系,并合成一个css
    //! style-loader会把css-loader生成的内容,以style挂载到页面的header部分
    use: ['style-loader', 'css-loader']
},
{
    test: /\.css$/,
    use:[
       {
          loader: 'style-loader',
          options: {
          injectType: 'singletonStyleTag' // 将所有的style标签合并成一个
           }
       }, 'css-loader'
    ]
}

Less样式处理(Scss一样)

less-loader 把less语法转换成css

npm install less less-loader -D
{
    test: /\.less$/,
    use: ['style-loader', 'css-loader', 'less-loader']
}
  • 样式自动添加前缀:postcss-loader
npm install postcss-loader autoprefixer -D

新建post.config.js

// webpack.config.js
{
    test: /\.css$/,
    use: ['style-loader', 'css-loader', 'postcss-loader']
}

// postcss.config.js
module.exports = {
    plugins: [
        require('autoprefixer')({
            overrideBrowserslist: ["last 2 versions", ">1%"] 
        })
    ]
}

5.plugins

plugin 可以在webpack运⾏行行到某个阶段的时候,帮你做⼀一些事情,类似于⽣生 命周期的概念

扩展插件,在 Webpack 构建流程中的特定时机注⼊入扩展逻辑来改变构建结 果或做你想要的事情。

作⽤用于整个构建过程

HtmlWebpackPlugin

htmlwebpackplugin会在打包结束后,自动⽣生成一个html文件,并把打包生 成的js模块引入到该html中。

npm install html-webpack-plugin -D

配置

title: 用来生成⻚页⾯面的 title 元素 
filename: 输出的 HTML 文件名,默认是 index.html, 也可以直接配置带有⼦目录。 
template: 模板文件路路径,支持加载器器,比如 html!./index.html 
inject: true | 'head' | 'body' | false  ,注⼊入所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素 中。 
favicon: 添加特定的 favicon 路径到输出的 HTML 文件中。 
minify: {} | false , 传递 html-minifier 选项给 minify 输出 
hash: true | false, 如果为 true, 将添加⼀一个唯⼀一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件,对于解除 cache 很有⽤用。 
cache: true | false,如果为 true, 这是默认值,仅在文件修改之后才会发布文件。 
showErrors: true | false, 如果为 true, 这是默认值,错误信息会写入到 HTML ⻚页⾯面中 chunks: 允许只添加某些块 (比如,仅仅 unit test 块) 
chunksSortMode: 允许控制块在添加到页⾯面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto' 
excludeChunks: 允许跳过某些块,(比如,跳过单元测试的块) 

// 示例
const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [ //! 插件配置
        new HtmlWebpackPlugin({
            title: 'My App',
            filename: 'app.name',
            template: './src/index.html'
        })
    ]
// index.html
<!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>
</body>
</html>

clean-webpack-plugin

clean-webpack-plugin会先删除之前打包生成的dist目录,然后在生成最新的打包后的dist

npm install clean-webpack-plugin -D

示例:

const { CleanWebpackPlugin } = require("clean-webpack-plugin");
plugins: [    
    new CleanWebpackPlugin() 
]

mini-css-extract-plugin

npm install mini-css-extract-plugin -D

示例:

const MiniCssExtractplugin = require('mini-css-extract-plugin')

{
    test: /\.css$/,
    use: [MiniCssExtractplugin.loader, 'css-loader']
}

new MiniCssExtractplugin({
    filename: '[name][chunkhash:8].css'
})

6.sourceMap

www.webpackjs.com/configurati…

源代码与打包后的代码的映射关系,通过sourceMap定位到源代码。 在dev模式中,默认开启,关闭的话 可以在配置⽂文件⾥里里

devtool: 'none'

eval: 速度最快,使用eval包裹模块代码, source-map: 产生 .map ⽂文件 cheap: 较快,不包含列列信息 Module:第三方模块,包含loader的sourcemap(比如jsx to js ,babel的 sourcemap) inline: 将 .map 作为DataURI嵌⼊入,不不单独⽣生成 .map ⽂文件

配置推荐

devtool:"cheap-module-eval-source-map",// 开发环境配置

//线上不不推荐开启 
devtool:"cheap-module-source-map",   // 线上⽣生成配置