webpack模块详解

package.json 初始化命令
npm init -y
webpack本地安装
npm install webpack@4.43.0 webpack-cli@3.3.12 -D
执行webpack (在root目录下建立src文件夹,默认入口文件index.js)

  1. npx webpack
  2. package.json scripts配置
    执行npm run dev
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
   "dev" : "webpack" ,
  },
Hash: 4eca0a58b43138af5e26
Version: webpack 4.43.0
Time: 193ms
Built at: 2021-04-02 6:26:08 ├F10: PM┤
  Asset       Size  Chunks             Chunk Names
main.js  958 bytes       0  [emitted]  main
Entrypoint main = main.js
[0] ./src/index.js 30 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

webpack默认执行构建mode=production (默认开启代码压缩插件)

查看Webpack版本号 npx webpack -v

配置webpack
建立 webpack.config.js 文件

  1. 初始配置
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    // 输出的文件存放的目录,必须是绝对路径
    path: path.resolve(__dirname, "./dist"),
    // 输出的文件名称
    filename: "main.js",
  },
  //指定开发模式
  mode: "development",
}

开发模式Mode⽤来指定当前的构建环境
production
development
none
设置mode可以⾃动触发webpack内置的函数,达到优化的效果
开发阶段的开启会有利于热更新的处理,识别哪个模块变化
⽣产阶段的开启会有帮助模块压缩,处理副作⽤等⼀些功能

  1. 定义自己的配置文件名
    package.json
{
  "name": "webpack_demo_01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --config ./webpack.[youname].js" // 指定自己webpack文件
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {},
  "devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.12"
  }
}
  1. 多入口——多出口应用
const path = require("path");

module.exports = {
  //entry: "./src/index.js",
  // 多入口应用——多入口一定要对应多出口
  entry: {
    index: "./src/index.js",
    a: "./src/a.js"
  },
  output: {
    // 输出的文件存放的目录,必须是绝对路径
    path: path.resolve(__dirname, "./dist"),
    // 输出的文件名称
    filename: "[name].js", // 占位符应用多出口文件
  },
  //指定开发模式
  mode: "development",
}

字符串和数组——单页面应用
对象——单、多页面应用

  1. 核心概念

chunk:指代码块,⼀个 chunk 可能由多个模块组合⽽成,也⽤于代码合并与分割。

bundle:资源经过Webpack 流程解析编译后最终结输出的成果⽂件。

entry:顾名思义,就是⼊⼝起点,⽤来告诉webpack⽤哪个⽂件作为构建依赖图的起点。
webpack会根据entry递归的去寻找依赖,每个依赖都将被它处理,最后输出到打包成果中。

output:output配置描述了webpack打包的输出配置,包含输出⽂件的命名、位置等信息。

loader:默认情况下,webpack仅⽀持 .js .json⽂件,通过loader,可以让它解析其他类型的⽂件,充当翻译官的⻆⾊。理论上只要有相应的loader,就可以处理任何类型的⽂件。

plugin:loader主要的职责是让webpack认识更多的⽂件类型,⽽plugin的职责则是让其可以控制构建流程,从⽽执⾏⼀些特殊的任务。插件的功能⾮常强⼤,可以完成各种各样的任务。
webpack的功能补充

mode:4.0开始,webpack⽀持零配置,旨在为开发⼈员减少上⼿难度,同时加⼊了mode的概念,⽤于指定打包的⽬标环境,以便在打包的过程中启⽤webpack针对不同的环境下内置的优化。
`

  1. css loader
    安装loader示例 npm install style-loader css-loader -D
    webpack 配置
const path = require("path");

module.exports = {
  //entry: "./src/index.js",
  // 多入口应用——多入口一定要对应多出口
  entry: {
    index: "./src/index.js",
    a: "./src/a.js"
  },
  output: {
    // 输出的文件存放的目录,必须是绝对路径
    path: path.resolve(__dirname, "./dist"),
    // 输出的文件名称
    filename: "[name].js", // 占位符应用多出口文件
  },
  //指定开发模式
  mode: "development",
  module: {
    rules: [
      {
        test: /\.css$/,
      use: ["style-loader", "css-loader"] // 多个loader情况下,执行顺序自后往前
      },
    ]
  }
}
  1. file-loader url-loader
    url-loader 和 file-loader 都可以⽤来处理本地的资源⽂件,如图⽚、字体、⾳视频等。功能也是
    类似的, 不过url-loader 可以指定在⽂件⼤⼩⼩于指定的限制时,返回 DataURL ,不会输出真实的⽂件,可以减少昂贵的⽹络请求。
    npm install url-loader file-loader -D
const path = require("path");
const htmlwebpackplugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  //entry: "./src/index.js",
  // 多入口应用——多入口一定要对应多出口
  entry: {
    index: "./src/index.js"
  },
  output: {
    // 输出的文件存放的目录,必须是绝对路径
    path: path.resolve(__dirname, "./dist"),
    // 输出的文件名称
    filename: "[name].js", // 占位符应用多出口文件
  },
  //指定开发模式
  mode: "development",
  resolveLoader: {
    modules: ["node_modules", "./myLoaders"], // 自定义寻找loader的目录,用于自定义loader
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
        use: [
          {
            loader: 'file-loader', // 仅配置url-loader即可,内部会⾃动调⽤file-loader
            options: {
              // limit: 10240, //⼩于此值的⽂件会被转换成DataURL
              name: '[name]_[hash:6].[ext]', // 设置输出⽂件的名字
              publicPath: "../images", // 设置其他文件调用资源的目录
              outputPath: 'images', // 设置资源输出的⽬录
            }
          }
        ],
      },
    ]
  },
  plugins: [
    new htmlwebpackplugin({
      template: "./src/index.html",
      filename: "index.html"
    }),
    new MiniCssExtractPlugin({
      filename: "css/[name][chunkhash:8].css"
    })
  ],
};

limit的设置要设置合理,太⼤会导致JS⽂件加载变慢,需要兼顾加载速度和⽹络请求次数。
如果需要使⽤图⽚压缩功能,可以使⽤ image-webpack-loader

  1. 开发自己的loader
# my-css-loader.js
module.exports = function (source) {
  return JSON.stringify(source);
}
# my-less-loader.js
const less = require("less");

module.exports = function (source) {
  less.render(source, (error, output) => {
    this.callback(error, output.css);
  });
}
# my-style-loader.js
module.exports = function (source) {
  // 动态创建style标签 把source放入style标签 把style标签放到文档头部
  return `
    const style = document.createElement("style");
    style.innerHTML = ${source};
    document.head.appendChild(style);
  `
}
  1. postCss
    postcss主要功能只有两个:第⼀就是把css解析成JS可以操作的抽象语法树AST,第⼆就是调⽤插件来处理AST并得到结果;所以postcss⼀般都是通过插件来处理css,并不会直接处理
    ⽐如:
    ⾃动补⻬浏览器前缀: autoprefixer
    css压缩等 cssnano
    npm install postcss-loader autoprefixer cssnano -D
# 创建postcss.config.js
# 配置postcss.config.js
module.exports = {
plugins: [require("autoprefixer")],
};
# 配置package.json
"browserslist":["last 2 versions", "> 1%"],
# 或者直接在postcss.config.js⾥配置
module.exports = {
plugins: [
require("autoprefixer")({
overrideBrowserslist: ["last 2 versions", "> 1%"],
}),
],
};
# 或者创建.browserslistrc⽂件
> 1%
last 2 versions
not ie <= 8
  1. 处理不同的字体
//css
@font-face {
font-family: "webfont";
font-display: swap;
src: url("webfont.woff2") format("woff2");
}
body {
background: blue;
font-family: "webfont" !important;
}
//webpack.config.js
{
test: /\.(eot|ttf|woff|woff2|svg)$/,
use: "file-loader"
}
  1. 常见插件
    (1)mini-css-extract-plugin
    经过如上⼏个loader处理,css最终是打包在js中的,运⾏时会动态插⼊head中,但是我们⼀般在⽣产环境会把css⽂件分离出来(有利于⽤户端缓存、并⾏加载及减⼩js包的⼤⼩),这时候就⽤到 mini-cssextract-plugin 插件。
    npm install mini-css-extract-plugin -D
# 使⽤
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [
{
    test: /\.less$/,
    use: [
    // 插件需要参与模块解析,须在此设置此项,不再需要style-loader
    {
        loader: MiniCssExtractPlugin.loader,
        options: {
                hmr: true, // 模块热替换,仅需在开发环境开启
                // reloadAll: true,
                // ... 其他配置
                      }
    },
    'css-loader','postcss-loader','less-loader']
    }
  ],
},
plugins: [
        new MiniCssExtractPlugin({
                      filename: '[name].css', // 输出⽂件的名字
                      // ... 其他配置
                      }),
          ]
};

(2) HtmlWebpackPlugin
htmlwebpackplugin会在打包结束后,⾃动⽣成⼀个html⽂件,并把打包⽣成的js模块引⼊到该html中。

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

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 path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
        ...
        plugins: [
        new htmlWebpackPlugin({
        title: "My App",
        filename: "app.html",
        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" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>

(3)clean-webpack-plugin
npm install --save-dev clean-webpack-plugin

const { CleanWebpackPlugin } = require("clean-webpack-plugin");
        ...
        plugins: [
            new CleanWebpackPlugin({
               // 如何做到dist⽬录下某个⽂件或⽬录不被清空
              // 清空操作排除dll⽬录,和dll⽬录下所有文件
                cleanOnceBeforeBuildPatterns: ["/*", "!dll", "!dll/"],
            })
        ]
  1. 构建通用配置文件实现打包多入口应用

  2. sourceMap
    源代码与打包后代码的关系映射

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容