郭世都

  • 主页
所有文章 友链 关于我

郭世都

  • 主页

webpack个人理解

2019-08-05

概念

在官方文档上是这么说的:“本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)”。我理解为webpack就是将一套包含很多类型文件(如js、hbs、cjs、sass、png等)的程序,打包成js、css、jpg、png等。

入口(entry)

入口,顾名思义:是从哪个或者说哪些地方进入。在webpack中是指定从哪个模块作为起点开始构建内部依赖图。再进入入口后,webpack会找出那些与入口存在依赖(直接或间接)关系的模块和库。之后每个依赖变会被进行处理,最后输出到bundles的文件中。
入口可以通过在webpack.config.js中进行配置(默认为./src),这个src就是我们一般在Vue-cli操作的那个文件夹。
入口可以是一个也可以是多个(就如同一个房子可以有一个门,也可以有多个门一样):
一个直接配置:

1
2
3
module.exports = {
entry: './path/to/my/entry/file.js'
};

多个则用对象的方式来配置。如:

1
2
3
4
entry: { // pagesDir是准备好的入口文件集合目录的路径 ------  ./src
'index/login': path.resolve(pagesDir, `./index/login/page`),
'index/index': path.resolve(pagesDir, `./index/index/page`),
},

出口(output)

出口(output属性)告诉webpack在哪里输出它所创建的bundles,以及如何命名这些文件。默认为./dist(默认在此路径下输出)。整个应用程序结构,基本都会编译到指定的输出路径的文件夹中。出口(output属性)可以在webpack.js中指定一个output字段来进行配置。如:

1
2
3
4
5
6
7
8
9
10
const path = require('path');//Node.js中的核心功能模块,用于操作文件路径
module.exports = {
entry: './path/to/my/entry/file.js',//入口配置
output: {
path: path.resolve(__dirname, 'dist'),//bundle生成的地方
filename: 'my-first-webpack.bundle.js'//webpack bundle 的名称
}
};

const path = require('path');

loader

webpack本身是只理解JavaScript的。无法处理其他文件,而loader则可以将所有类型的文件转换为webpack能够处理的有效模块。这样就能用webpack的打包能力,对他们进行处理。
官方文档:本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
在webpack的配置中loader有两个属性:
test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
use 属性,表示进行转换时,应该使用哪个 loader。
如在webpack.config.js文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
const path = require('path');//Node.js中的核心功能模块,用于操作文件路径
const config = {
output: {//出口配置
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [//loader配置
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};

module.exports = config;

这样在webpack的编译器读到在require()或import语句中解析为’.txt’的路径(txt文件)时,在对他打包之前,先使用raw-loader转换一下。
loader有很多种,分别对应不同的文件类型(TypeScript、CSS等),在使用loader进行转换之前需要先安装对应的loader。如:

1
2
npm install --save-dev css-loader
npm install --save-dev ts-loader

然后就可以让webpack对每个.css文件使用css-loader,以及对所有.ts文件使用ts-loader,配置如下:
在webpack.config.js文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const path = require('path');//Node.js中的核心功能模块,用于操作文件路径
const config = {
output: {//出口配置
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};

module.exports = config;

还可以在cli(命令行界面)使用loader(推荐在配置文件webpack.config.js的module.rules中写配置,方便管理,简化代码),如:

1
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

这会对 .jade 文件使用 jade-loader,对 .css 文件使用 style-loader 和 css-loader。

还可以用内联方式来写(推荐在配置文件webpack.config.js的module.rules中写配置,方便管理,简化代码):

1
import Styles from 'style-loader!css-loader?modules!./styles.css';

可以在 import 语句或任何等效于 “import” 的方式中指定 loader。使用 ! 将资源中的 loader 分开。分开的每个部分都相对于当前目录解析。
选项可以传递查询参数,例如 ?key=value&foo=bar,或者一个 JSON 对象,例如 ?{“key”:”value”,”foo”:”bar”}。

插件(plugins)

插件的功能极其强大与丰富,可以用来处理很多任务。
在使用一个插件时,要先用require()它并且把它存入一个常量(用const代替var或let创建的)中,然后把常量添加到plugins数组中,大多数插件可以通过选项(option)自定义。也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。
案例:安装html-webpack-plugin插件,此插件的基本作用就是生成Html文件

1
npm install html-webpack-plugin --save-dev
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装的插件
const webpack = require('webpack'); // 用于访问内置插件

const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',//制定生成Html的模板
title: "hello world"//标题
})//new 的HtmlWebpackPlugin实例并在其中传入参数(是一个对象),可传入的参数还有很多具体可看https://www.cnblogs.com/wonyun/p/6030090.html
]
};

module.exports = config;

模式

在配置文件中

1
2
3
module.exports = {
mode: 'production'//默认值,生产模式
}
值 描述
production 默认值,生产模式。会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.
development 开发模式。会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
none 不使用优化

在production生产模式中会自动进行如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
module.exports = {
// mode: 'production', 相当于配置了以下内容
performance: {
hints: 'warning'
},
output: {
pathinfo: false
},
optimization: {
namedModules: false,
namedChunks: false,
nodeEnv: 'production',
flagIncludedChunks: true,
occurrenceOrder: true,
sideEffects: true,
usedExports: true,
concatenateModules: true,
splitChunks: {
hidePathInfo: true,
minSize: 30000,
maxAsyncRequests: 5,
maxInitialRequests: 3,
},
noEmitOnErrors: true,
checkWasmTypes: true,
minimize: true,
},
plugins: [
new UglifyJsPlugin(/* ... */),
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.NoEmitOnErrorsPlugin()
]
}

在development开发模式中会自动进行如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module.exports = {
// mode: 'development' 相当于配置了以下内容
devtool: 'eval',
cache: true,
performance: {
hints: false
},
output: {
pathinfo: true
},
optimization: {
namedModules: true,
namedChunks: true,
nodeEnv: 'development',
flagIncludedChunks: false,
occurrenceOrder: false,
sideEffects: false,
usedExports: false,
concatenateModules: false,
splitChunks: {
hidePathInfo: false,
minSize: 10000,
maxAsyncRequests: Infinity,
maxInitialRequests: Infinity,
},
noEmitOnErrors: false,
checkWasmTypes: false,
minimize: false,
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.NamedChunksPlugin(),
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
]
}

none 不使用优化时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module.exports = {
// mode: 'none', 相当于配置了以下内容
performance: {
hints: false
},
optimization: {
flagIncludedChunks: false,
occurrenceOrder: false,
sideEffects: false,
usedExports: false,
concatenateModules: false,
splitChunks: {
hidePathInfo: false,
minSize: 10000,
maxAsyncRequests: Infinity,
maxInitialRequests: Infinity,
},
noEmitOnErrors: false,
checkWasmTypes: false,
minimize: false,
},
plugins: []
}

在production模式下会启用UglifyJsPlugin插件(移除未使用的内容和文件压缩),分别用production和development打包,编译的区别:

1.development打包后,一些没有依赖的方法、变量、文件会保留,production则会移除。

2.production打包后,代码会进行压缩,比development的文件小。

常用方式–config
一般开发项目时,会自定义配置文件,例如:webpack.base.config.js(公共配置)、webpack.dev.cinfig.js(开发配置)、webpack.prod.config.js(生产配置)。

并分别在开发配置和生产配置中指定mode,在运行webpack时用–config命令指定使用的配置文件。来代替直接指定模式–mode。

1
build: 'webpack --config build/webpack.dev.config.js'

webpack热替换

webpack目前不支持在生产环境中使用,所以作用是加快开发速度。
启用方法:因为是个插件(webpack内置插件),所以跟之前说的插件使用方法一样。
别了在写入内置插件之前要有

1
var webpack = require("webpack");
1
2
3
4
5
6
new webpack.HotModuleReplacementPlugin({
// Options...//参数一般是不用传,具体可传参数也是实验性,随时可能被放弃,所以不多说,如下:
// multiStep (boolean):设置为 true 时,插件会分成两步构建文件。首先编译热加载 chunks,之后再编译剩余的通常的资源。
// fullBuildTimeout (number):当 multiStep 启用时,表示两步构建之间的延时。
// requestTimeout (number):下载 manifest 的延时(webpack 3.0.0 后的版本支持)。
})

如果已经启用了模块热替换,则它的接口则将被暴露在module.hot属性下,用法例:

1
2
3
4
5
if (module.hot) {//首先判断接口是否可用
module.hot.accept('./library.js', function() {//module.hot属性下的accept方法,第一个参数的数据类型可以是字符串或者字符串数组,第二个是回调函数,可以使用更新过后的模块进行某些操作
// 使用更新过的 library 模块执行某些操作...
})
}

其他方法类似,具体使用方法可看官方文档 https://www.webpackjs.com/api/hot-module-replacement/

赏

谢谢你为我点赞

支付宝
微信
  • 个人理解

扫一扫,分享到微信

微信分享二维码
数组循环(含ES6)
关于手机照片放入img 标签中被旋转问题
  1. 1. 概念
  2. 2. 入口(entry)
  3. 3. 出口(output)
  4. 4. loader
  5. 5. 插件(plugins)
  6. 6. 模式
  7. 7. webpack热替换

0 评论
Powered By Valine
v1.5.2
© 2019 郭世都
  • 所有文章
  • 友链
  • 关于我

tag:

  • 安装总结
  • ES6
  • Vue
  • 日常工作
  • 个人理解

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 前端编程模块化

    2019-08-12

    #ES6

  • Promise

    2019-08-12

    #ES6

  • 伪数组

    2019-08-09

    #ES6

  • axios 相关配置及注解

    2019-08-09

    #Vue

  • qs插件

    2019-08-09

    #Vue

  • 数组循环(含ES6)

    2019-08-07

    #ES6

  • webpack个人理解

    2019-08-05

    #个人理解

  • 关于手机照片放入img 标签中被旋转问题

    2019-07-24

    #日常工作

  • Hexo 功能添加

    2019-07-22

    #安装总结

  • vue--事件总线初接触

    2019-07-22

    #Vue

  • Hexo个人安装总结

    2019-07-20

    #安装总结

  • 友情链接1
  • 友情链接2
  • 友情链接3
  • 友情链接4
  • 友情链接5
  • 友情链接6
本人擅长Ai、Fw、Fl、Br、Ae、Pr、Id、Ps等软件的安装与卸载,精通CSS、JavaScript、PHP、ASP、C、C++、C#、Java、Ruby、Perl、Lisp、python、Objective-C、ActionScript、Pascal、spss、sas等单词的拼写,熟悉Windows、Linux、Mac、Android、IOS、WP8等系统的开关机。