文档章节

Webpack配置

hezhongjie
 hezhongjie
发布于 2017/05/03 12:45
字数 2984
阅读 4
收藏 0
点赞 0
评论 0

Webpack是目前基于React和Redux开发的应用的主要打包工具。我想使用Angular 2或其他框架开发的应用也有很多在使用Webpack。

当我第一次看到Webpack的配置文件时,它看起来非常的陌生,我非常的疑惑。经过一段时间的尝试之后我认为这是因为Webpack只是使用了比较特别的语法和引入了新的原理,因此会让使用者感到疑惑。这些也是导致Webpack不被人熟悉的原因。

因为刚开始使用Webpack很让人疑惑,我觉得有必要写几篇介绍Webpack的功能和特性的文章以帮助初学者快速理解。此文是最开始的一篇。

Webpack的核心原理

Webpack的两个最核心的原理分别是:

  1. 一切皆模块 正如js文件可以是一个“模块(module)”一样,其他的(如css、image或html)文件也可视作模 块。因此,你可以require('myJSfile.js')亦可以require('myCSSfile.css')。这意味着我们可以将事物(业务)分割成更小的易于管理的片段,从而达到重复利用等的目的。

  2. 按需加载 传统的模块打包工具(module bundlers)最终将所有的模块编译生成一个庞大的bundle.js文件。但是在真实的app里边,“bundle.js”文件可能有10M到15M之大可能会导致应用一直处于加载中状态。因此Webpack使用许多特性来分割代码然后生成多个“bundle”文件,而且异步加载部分代码以实现按需加载。

好了,下面来看看那些令人困惑的部分吧。

  1. 开发模式和生产模式

    首先要知道的是Webpack有许许多多的特性,一些是”开发模式“下才有的,一些是”生产模式“下才有的,还有一些是两种模式下都有的。

    输入图片说明

通常使用到Webpack如此多特性的项目都会有两个比较大的Webpack配置文件 为了生成bundles文件你可能在package.json文件加入如下的scripts项:

"scripts": {
// 运行npm run build 来编译生成生产模式下的bundles
"build": "webpack --config webpack.config.prod.js",
// 运行npm run dev来生成开发模式下的bundles以及启动本地server
"dev": "webpack-dev-server"
}
  1. webpack CLI 和webpack-dev-server

    值得注意的是,Webpack作为模块打包工具,提供两种用户交互接口:

    a.Webpack CLI tool:默认的交互方式(已随Webpack本身安装到本地)

    b.webpack-dev-server:一个Node.js服务器(需要开发者从npm自行安装)

    Webpack CLI(有利于生产模式下打包) 这种方式可以从命令行获取参数也可以从配置文件(默认叫webpack.config.js)获取,将获取到的参数传入 Webpack来打包。

    当然你也可以从命令行(CLI)开始学习Webpack,以后你可能主要在生产模式下使用到它。

    用法:

    方式1:

// 全局模式安装webpack npm install webpack --g // 在终端输入 $ webpack // <--使用webpack.config.js生成bundle ```

方式 2 :

```
// 非全局模式安装webpack然后添加到package.json依赖里边
npm install webpack --save
// 添加build命令到package.json的scripts配置项
"scripts": {
 "build": "webpack --config webpack.config.prod.js -p",

 }
// 用法:
"npm run build"

 webpack-dev-server(有利于在开发模式下编译):    这是一个基于Express.js框架开发的web server,默认监听8080端口。server内部调用Webpack,这样做的好处是提供了额外的功能如热更新“Live Reload”以及热替换“Hot Module Replacement”(即HMR)。

 用法:

   方式 1:

 ```
// 全局安装
npm install webpack-dev-server --save
// 终端输入
$ webpack-dev-server --inline --hot
用法 2:

```

// 添加到package.json scripts "scripts": { "start": "webpack-dev-server --inline --hot", } // 运行: $ npm start // 浏览器预览: http://localhost:8080


    Webpack VS Webpack-dev-server选项

   注意像inline和hot这些选项是Webpack-dev-server特有的,而另外的如hide-modules则是CLI模式特有的选项。

    webpack-dev-server CLI选项和配置项 : 另外值得注意的是你可以通过以下两种方式向webpack-dev-server传入参数:

    1.通过webpack.config.js文件的"devServer"对象
    ```
// 通过webpack.config.js传参
devServer: {
  inline: true,
  hot:true
}
2.通过CLI选项

// 通过CLI传参

    webpack-dev-server --hot --inline

我发现有时devServer配置项(hot: true 和inline: true)不生效,我更偏向使用如下的方式向CLI传递参数:

```

// package.json { "scripts": "webpack-dev-server --hot --inline" } //注意:确定你没有同时传入hot:true和-hot

   
    webpack-dev-server的“hot” 和 “inline”选项 : “inline”选项会为入口页面添加“热加载”功能,“hot”选项则开启“热替换(Hot Module Reloading)”,即尝试重新加载组件改变的部分(而不是重新加载整个页面)。如果两个参数都传入,当资源改变时,webpack-dev-server将会先尝试HRM(即热替换),如果失败则重新加载整个入口页面。

    // 当资源发生改变,以下三种方式都会生成新的bundle,但是又有区别:

    ```
// 1. 不会刷新浏览器
$ webpack-dev-server
//2. 刷新浏览器
$ webpack-dev-server --inline
//3. 重新加载改变的部分,HRM失败则刷新页面
$ webpack-dev-server  --inline --hot
  1. “entry”:值分别是字符串、数组和对象的情况

    Enter配置项告诉Webpack应用的根模块或起始点在哪里,它的值可以是字符串、数组或对象。这看起来可能令人困惑,因为不同类型的值有着不同的目的。 像绝大多数app一样,倘若你的应用只有一个单一的入口,enter项的值你可以使用任意类型,最终输出的结果都是一样的。 图片描述

    enter:数组类型

    但是,如果你想添加多个彼此不互相依赖的文件,你可以使用数组格式的值。 例如,你可能在html文件里引用了“googleAnalytics.js”文件,可以告诉Webpack将其加到bundle.js的最后。 图片描述

    enter:对象

    现在,假设你的应用是多页面的(multi-page application)而不是SPA,有多个html文件(index.html和profile.html)。然后你通过一个对象告诉Webpack为每一个html生成一个bundle文件。 以下的配置将会生成两个js文件:indexEntry.js和profileEntry.js分别会在index.html和profile.html中被引用。

    图片描述

    用法:

  //profile.html
<script src=”dist/profileEntry.js”></script>
//index.html
<script src=”dist/indexEntry.js”></script>

注意:文件名取自“entry”对象的键名。

enter:混合类型

你也可以在enter对象里使用数组类型,例如下面的配置将会生成3个文件:vender.js(包含三个文件),index.js和profile.js文件。

  ![图片描述](https://static.oschina.net/uploads/img/201705/03123917_AjGS.png "在这里输入图片标题")
  1. output:“path”项和“publicPath”项

    output项告诉webpack怎样存储输出结果以及存储到哪里。output的两个配置项“path”和“publicPath”可能会造成困惑。

    “path”仅仅告诉Webpack结果存储在哪里,然而“publicPath”项则被许多Webpack的插件用于在生产模式下更新内嵌到css、html文件里的url值。

    图片描述

    例如,在localhost(译者注:即本地开发模式)里的css文件中边你可能用“./test.png”这样的url来加载图片,但是在生产模式下“test.png”文件可能会定位到CDN上并且你的Node.js服务器可能是运行在HeroKu上边的。这就意味着在生产环境你必须手动更新所有文件里的url为CDN的路径。

    然而你也可以使用Webpack的“publicPath”选项和一些插件来在生产模式下编译输出文件时自动更新这些url。

    图片描述

// 开发环境:Server和图片都是在localhost(域名)下 .image { background-image: url('./test.png'); } // 生产环境:Server部署下HeroKu但是图片在CDN上 .image { background-image: url('https://someCDN/test.png'); }


5. 模块加载和链式模块加载

    模块加载器是可自由添加的Node模块,用于将不同类型的文件“load”或“import”并转换成浏览器可以识别的类型,如js、Stylesheet等。更高级的模块加载器甚至可以支持使用ES6里边的“require”或“import”引入模块。

    例如,你可以使用babel-loader来将使用ES6语法写成的文件转换成ES5:

    ```
module: {
 loaders: [{
  test: /\.js$/, // 匹配.js文件,如果通过则使用下面的loader
  exclude: /node_modules/, // 排除node_modules文件夹
  loader: 'babel' // 使用babel(babel-loader的简写)作为loader
 }]
链式(管道式)的加载器(从右往左执行)多个loader可以用在同一个文件上并且被链式调用。链式调用时从右到左执行且loader之间用“!”来分割。

例如,假设我们有一个名为“myCssFile.css”的css文件,然后我们想将它的内容使用style标签内联到最终输出的html里边。我们可以使用css-loader和style-loader两个loader来达到目的。

```

module: { loaders: [{ test: /.css$/, loader: 'style!css' //(short for style-loader!css-loader) }]


    这里展示它是如何工作的:
   ![输入图片说明](https://static.oschina.net/uploads/img/201705/03135006_8uHF.png "在这里输入图片标题")

    Webpack在模块颞部搜索在css的依赖项,即Webpack检查js文件是否有“require('myCssFile.css')”的引用,如果它发现有css的依赖,Webpack将css文件交给“css-loader”去处理css-loader加载所有的css文件以及css自身的依赖(如,[@import](https://my.oschina.net/u/3201731) 其他css)到JSON对象里,Webpack然后将处理结果传给“style-loader”

    style-loader接受JSON值然后添加一个style标签并将其内嵌到html文件里

6. loader自身可以配置
模块加载器(loader)自身可以根据传入不同的参数进行配置。
在下面的例子中,我们可以配置url-loader来将小于1024字节的图片使用DataUrl替换而大于1024字节的图片使用url,我们可以用如下两种方式通过传入“limit“参数来实现这一目的:
![图片描述](https://static.oschina.net/uploads/img/201705/03124443_CHYU.png "在这里输入图片标题")

7. .babelrc 文件

    babal-loader使用”presets“配置项来标识如何将ES6语法转成ES5以及如何转换React的JSX成js文件。我们可以用如下的方式使用”query“参数传入配置:

    ```
module: {
  loaders: [
    {
      test: /\.jsx?$/,
      exclude: /(node_modulesbower_components)/,
      loader: 'babel',
      query: {
        presets: ['react', 'es2015']
      }
    }
  ]
}
然而在很多项目里babal的配置可能比较大,因此你可以把babal-loader的配置项单独保存在一个名为”.babelrc“的文件中,在执行时babal-loader将会自动加载.babelrc文件。

所以在很多例子里,你可能会看到:

```

//webpack.config.js module: { loaders: [ { test: /.jsx?$/, exclude: /(node_modulesbower_components)/, loader: 'babel' } ] } //.bablerc { presets: ['react', 'es2015'] } ```

  1. 插件

    插件一般都是用于输出bundle的node模块。

    例如,uglifyJSPlugin获取bundle.js然后压缩和混淆内容以减小文件体积。

    类似的extract-text-webpack-plugin内部使用css-loader和style-loader来收集所有的css到一个地方最终将结果提取结果到一个独立的”styles.css“文件,并且在html里边引用style.css文件。

//webpack.config.js // 获取所有的.css文件,合并它们的内容然后提取css内容到一个独立的”styles.css“里 var ETP = require("extract-text-webpack-plugin");

module: { loaders: [ {test: /.css$/, loader:ETP.extract("style-loader","css-loader") } ] }, plugins: [ new ExtractTextPlugin("styles.css") //Extract to styles.css file ] }


    注意:如果你只是想把css使用style标签内联到html里,你不必使用extract-text-webpack-plugin,仅仅使用css loader和style loader即可:

    ```
module: {
 loaders: [{
  test: /\.css$/,
  loader: 'style!css' // (short for style-loader!css-loader)
 }]
  1. 加载器(loader)和插件

    你可能已经意识到了,Loader处理单独的文件级别并且通常作用于包生成之前或生成的过程中。

    而插件则是处理包(bundle)或者chunk级别,且通常是bundle生成的最后阶段。一些插件如commonschunkplugin甚至更直接修改bundle的生成方式。

    1. 处理文件的扩展名

    很多Webpack的配置文件都有一个resolve属性,然后就像下面代码所示有一个空字符串的值。空字符串在此是为了resolve一些在import文件时不带文件扩展名的表达式,如require('./myJSFile')或者import myJSFile from './myJSFile'(译者注:实际就是自动添加后缀,默认是当成js文件来查找路径)

{ resolve: { extensions: ['', '.js', '.jsx'] } }



就这么多。

作者: 极客教程 
链接:http://www.imooc.com/article/13357
来源:慕课网

© 著作权归作者所有

共有 人打赏支持
hezhongjie
粉丝 2
博文 28
码字总数 41289
作品 0
程序员
webpack多页面配置记录

之前也写过webpack学习记录,项目中需要一个常用的webpack多页面配置,所以才动手,本着能写一行是一行的原则,开始了配置webpack之旅。 定目录结构 首先我只需要开发环境(包含自动更新)和...

走路不看手机 ⋅ 01/19 ⋅ 0

【翻译】Webpack 4 教程:从0配置到生产模式

原文链接:Webpack 4 Tutorial: from 0 Conf to Production Mode webpack 4 问世了! 这个流行的模块打包工具进行了大规模的升级。 webpack4,有什么更新?大幅度的性能优化,零配置和明智的...

Skandar-Ln ⋅ 05/15 ⋅ 0

webpack初试

接触webpack其实已经很久了,但是真正去研究它还是第一次,所以记录一下自己的学习体验: webpack的主要功能是:Webpack 是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工...

sunshinewyf ⋅ 2016/07/20 ⋅ 0

Webpack脚手架

1. 什么是webpack? webpack是一个现代Javascript应用程序的模块打包器,当webpack处理应用程序时,他会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包...

R_JsBest ⋅ 2017/12/04 ⋅ 0

Web 使用webpack构建前端项目

好久没写技术博客了, 原因在于最近在学习前端方面的技术, 熟悉我的同学都知道, 之前我有使用Vue搭建了一个个人简历, 体验了一把最新的前端技术, 但之前我们使用的是vue-cli脚手架工具, 对于如...

Castie1 ⋅ 2017/09/23 ⋅ 0

如何打造一个令人愉悦的前端开发环境(四)

原文链接 此文是我同事写的,搭建Express结合Webpack。以下是正文,后面我会附上我的解读 Express 结合 Webpack 实现HMR 本篇文件主要讲结合 Webpack 和 Express 实现前后端热更新开发,如果...

乖小鬼YQ ⋅ 2017/11/29 ⋅ 0

webpack 入门

1. 什么是webpack 官网介绍:webpack是一个模块打包器。webpack 处理带有依赖关系的模块,生成一系列表示这些模块的静态资源。(webpack is a module bundler.webpack takes modules with dep...

力谱宿云 ⋅ 2016/05/13 ⋅ 0

你所不知的Webpack-多种配置方法

除了通过最常见的导出一个 Object 来描述 Webpack 所需的配置外,还有其它更灵活的方式,以简化不同场景的配置。 下面来一一介绍它们。 导出一个 Function 在大多数时候你需要从同一份源代码...

⋅ 2017/12/20 ⋅ 0

webpack 先这么用

webpack 介绍 Webpack 是一个模块打包器。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源; 开发便捷,能替代部分 grunt/gulp 的工作,比如打包、压缩...

fabself ⋅ 2016/09/24 ⋅ 0

从零开始搭建React开发环境(一)

项目链接:github.com/MrZhang123/… 核心 React:16.3.2 React-dom:16.3.2 Webpack:4.6.0 React-router-dom:4.2.2 Redux:4.0.0 React-hot-loader:4.1.2 目录结构 基础搭建 首先搭建一个基础的......

Mello_fe ⋅ 05/12 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周三乱弹 —— 这样的女人私生活太混乱了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 胖达panda :你经历过体验到人生的大起大落吗?我一朋友在10秒内体验了,哈哈。@小小编辑 请点一首《almost lover》送给他。 《almost love...

小小编辑 ⋅ 38分钟前 ⋅ 5

自己动手写一个单链表

文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:好好学java,获取优质学习资源。 一、概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对...

公众号_好好学java ⋅ 44分钟前 ⋅ 0

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部