webpack入门记

题记

本年度的前端研究方向之一是webpack,之前就去看过一个webpack的学习视频,自己按照课程写了一些配置文件,对webpack的基本配置和使用有了一定的了解。后面参与开发智能客服和企业网关项目,使用了webpack+react+redux,开发过程读了很多次webpack的配置文件,并且进行了相应的修改,在实战中加强了对webpack的理解。想要整理一下相关的知识和经验,又回看了一遍之前的学习视频,有了很多新的领悟。这里要提醒自己,学习视频回看是很有必要的。

整体把控

首先我们要理解webpack是什么,一句话来解释就是一个模块打包器,一张图来解释就更为直观,下面是webpack官网的图示。

image.png

从图上可以看出,webpack可以把包含错综复杂依赖关系的模块化文件进行打包,生成若干静态文件。并且有处理多种类型文件的能力。

快速掌握

快速掌握webpack的使用,只需要了解四个核心概念。

  1. entry 指定程序入口文件,比如index.js文件。webpack会从这里开始解析各个文件之间的依赖关系并且进行处理。
    module.exports = {
    entry: './path/to/my/entry/index.js'
    };

  2. output指定打包好的文件的信息,路径和文件名都可以在这里指定。
    const path = require('path');

     module.exports = {
       entry: './path/to/my/entry/index.js',
       output: {
         path: path.resolve(__dirname, 'dist'),
         filename: 'my-first-webpack.bundle.js'
       }
     };
    
  3. loaders对各种文件类型进行转换,让只能处理JavaScriptwebpack可以处理多类型的文件。需要安装指定的loader。写这篇博客的时候时候webpack已经有了2.0版本,对于loaders的配置与1.0版本有一些不同,这里使用最新的写法进行举例。
    const path = require('path');

     const config = {
       entry: './path/to/my/entry/index.js',
       output: {
         path: path.resolve(__dirname, 'dist'),
         filename: 'my-first-webpack.bundle.js'
       },
       module: {
         rules: [
           { test: /\.css$/, use: 'css-loader' }
         ]
       }
     };
    
     module.exports = config;
    

在项目实战中,我们一般需要处理的文件有js,jsx,css,scss,less,png,jpg,gif还有一些没有列出来的音频视频文件等等,它们都有对应的loaders来处理。可以在使用的时候查看一下文档。

  1. plugins非常强大并且可定制。它的作用是什么呢,可以这样的简单理解一下,loaders是对没有打包前的文件做一些预处理的工作,plugins可以对编译和打包生成的块文件(当然,不仅仅局限于此)做一些操作或者实现一些自定义的功能。
    const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
    const webpack = require('webpack'); //to access built-in plugins
    const path = require('path');

    const config = {
      entry: './path/to/my/entry/index.js',
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'my-first-webpack.bundle.js'
      },
      module: {
        rules: [
          { test: /\.css$/, use: 'css-loader' }
        ]
      },
      plugins: [
        new webpack.optimize.UglifyJsPlugin(),
        new HtmlWebpackPlugin({template: './src/index.html'})
      ]
    };

    module.exports = config;

在项目实战中plugins是非常重要的一个环节,尤其是当你遇到一些问题,你会发现有很多问题都可以引入对应的插件来解决,后文也会有所介绍。上面例子中的两个plugins的功能分别是压缩打包文件和按照模板文件自动生成注入文件引用的index.html文件。

项目实战

  1. 配置文件目录

在看过学习视频,看过官方文档,还有自己写了一些小例子之后,以为实战开发会看到自己很熟悉的代码,没想到第一次看代码的时候打开根路径下的webpack.config.js文件,并没有看到自己熟悉的代码。因为在项目实战的时候会考虑到各种环境的配置文件,基于模块划分的思想,一般会有一个cfg文件夹,下面有基础配置文件,开发环境配置文件,线上环境配置文件,然后在webpack.config.js中根据不同的环境选择不同的配置文件。

  1. 关于图片的打包

图片文件有两个值得注意的问题。

第一个问题是,如果我们选用url-loader来处理图片文件的话,可以在后面跟一个limit参数,例如limit=8192,它的意思是,如果图片的大小小于limit,那么会在图片出现的位置用base64码的方式进行引用,省掉了http请求。如果不想用base64的方式引用,可以使用file-loader来进行处理。具体的选择需要结合项目中图片的具体情况。如果图片经常重复出现,那可能选用浏览器能够缓存的方式(也就是传统引用方式)会更加利于性能优化。

第二个问题是,在项目中的js模板代码中如果引入了图片文件,打包时我们会发现图片并没有成功引入。这时的处理方法是在js代码中用require的方式将图片引入,这样webpack在处理的时候会将图片作为一个模块,打包进依赖树。

  1. 关于打包文件版本号的添加

部署环境的时候,为了代码能够时时的更新,我们需要在静态资源文件上加上版本号。webpack可以很简单的做好这个工作,只需要我们在线上环境的配置文件中将output配置修改一下即可。
output: {
path: path.join(__dirname, '/../dist'),
filename: '/assets/[name]-[Hash].js'
}
这样子生成的js文件会带上五位的hash值,在代码变动之后hash值也会发生相应的变化,从而保证浏览器不会使用缓存过的静态资源文件,而是请求最新的静态资源文件。

生成了带版本号的静态资源文件之后,接下来要解决的问题是在index.html 中进行引用,总不能每次手动去根据最新的文件名来修改该文件。这时候,有强大的plugins系统来解决我们的问题。
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const path = require('path');

     const config = {
       entry: './path/to/my/entry/index.js',
       output: {
         path: path.resolve(__dirname, 'dist'),
         filename:'/assets/[name]-[Hash].js'
       },
       module: {
         rules: [
           { test: /\.css$/, use: 'css-loader' }
          ]
       },
       plugins: [
         new HtmlWebpackPlugin({
           template:'src/index.html',
           filename:'index.html',
           inject:'body'
         })
       ]
     };

     module.exports = config;

如上图示例,我们可以使用html-webpack-plugin来解决这个问题,这个插件可以设置模板文件的名称,生成文件的名称,并且指定静态文件引入的位置(例子中为body中引用)。这样子可以在打包之后获得一个引入了最新静态资源文件的index.html文件。解决了手动修改的问题。

但是,问题并没有到这里就结束。如果我们选用了src文件下的index.html文件作为模板文件,我们会发现打包生成的index.html文件中不仅仅引入了带hash值的js文件,还有<script type="text/javascript" src="/assets/app.js"></script>这样的一行代码。原因也很简单,因为src文件下的index.html引入了js文件。解决方法非常简单,新建一个干净的没有引入js文件的模板文件即可解决。但是我们需要搞清楚的是,为什么src文件下的index.html文件一定要引入这样的js文件呢,为什么不能用同样的方式,动态去插入引用的代码呢。这个问题困扰了我很久,最后我找到了原因。这是因为在项目中开发环境我们使用了webpack-dev-server来起项目,其实它就是一个小型的轻量的Node.js Express服务器。它需要默认入口路径中有一个index.html文件,并且引入打包生成的静态资源文件(这个文件并没有真正的放在你的真实目录中,而是放在了内存中)。如果你的项目中没有使用webpack-dev-server,而是自己配置了一个Express,就可以避免这个问题,只用一个干净的模版index.html文件就可以生成开发环境和线上环境需要的index.html文件了。

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

推荐阅读更多精彩内容

  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,697评论 7 110
  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,171评论 7 35
  • 学习流程 参考文档:入门Webpack,看这篇就够了Webpack for React 一. 简单使用webpac...
    Jason_Zeng阅读 3,141评论 2 16
  • 熊二说要请我看电影,选择了嘉年华。 知道电影名字时,我没有去看电影介绍,仅凭对字面理解,以为这是一部欢快的影片。 ...
    花儿姐姐1977阅读 177评论 1 0
  • 瘦身成家出国吃天下, 是很多萌妹纸们的座右铭, 但只怕身子没瘦下来,爱人没遇到, 环游世界没有钱没有时间, 吃得美...
    一招鲜阅读 752评论 1 4