Gulp与Webpack相结合使用的场景案例分析

项目源码

有些事webpack真不好办

如此强大的webpack,有什么能难住ta?
在解答这个问题之前,我们介绍一些比较“冷”的知识

assets和public

项目会有很多的静态资源,理论上讲放在这俩文件下都能运行项目,但是有很大区别。

简单讲

  • assets:放在这的静态资源会经webpack处理,会经过打包优化加上内容hash等一系列美滋滋的加工。
  • public:以上都不能,尤其内容hash这块,你会为版本问题提心吊胆。

有些时候有些事情可以简单讲,但这里有必要“费劲”讲讲。

费劲讲

首先我们溯源,通过create-react-app上的官网看关于public文件夹的介绍,就能了解一二。

官方鼓励把静态资源放在assets

原文在这:

Note that we normally encourage you to import assets in JavaScript files instead

然后列出了三点优势:

  • 文件经过压缩尽可能的捆在一起了,文件数少了,自然请求就少,优化了性能。
  • 缺少文件,直接就会在webpack编译时就报错,这就很安全了。
  • 文件都打上了内容hash,不用为版本缓存问题发愁,美滋滋啊,简直太好了。

原文在这:

  • Scripts and stylesheets get minified and bundled together to avoid extra network requests.
  • Missing files cause compilation errors instead of 404 errors for your users.
  • Result filenames include content hashes so you don’t need to worry about browsers caching their old versions.

那么用pubclic呢,会有什么结果呢。

首先官网特别不推荐,并且ta说放在这里的资源并不会被webpack处理。

原文在这:

If you put a file into the public folder, it will not be processed by webpack.

同时使用资源的时候必须要带着PUBLIC_URL这个变量当前缀(上一篇讲electron文章里面已经贴出了解决办法

原文在这:

Only files inside the public folder will be accessible by %PUBLIC_URL% prefix.

然后的ta的缺点都是放在assets的优点的反面。

原文在这:

  • None of the files in public folder get post-processed or minified.
  • Missing files will not be called at compilation time, and will cause 404 errors for your users.
  • Result filenames won’t include content hashes so you’ll need to add query arguments or rename them every time they change.

什么时候用呢?

官网给出的策略是:

  • 当你用manifest.webmanifest这类的特定名称的文件(dllplugin会有涉及,有兴趣可以了解一下)
  • 你有非常多的图片要动态的使用。
  • 你需要引入一些脚本在项目之外
  • 你需要引入的一些库,其无法被webpack接受

原文在这:

  • You need a file with a specific name in the build output, such as manifest.webmanifest.
  • You have thousands of images and need to dynamically reference their paths.
  • You want to include a small script like pace.js outside of the bundled code.
  • Some libraries may be incompatible with webpack and you have no other option but to include it as a <script> tag.

那么综上所述,我接下来要解决的问题就符合了上面的第四点,无法被webpack接受😂。


我要解决什么问题

我要解决的问题其实很简单,就是把一个游戏🎮集成进到我的脚手架中来(集成的办法以后我会单独写文章讲),那么遇到的瓶颈是什么呢?

遇到的瓶颈

瓶颈就是游戏🎮项目并不被webpack接受,无法放在assets中,我就只好放在public中,那么就会有个问题,我无论是否需不需要该功能,都会把游戏包拷贝到项目中。。。。。这就尴尬了,应该按需加载啊,所以这是无法接受的,必须解决。

怎么解决尴尬

那么就是我不尴尬😄,尴尬的就是别人,开玩笑,开玩笑,同学请把刀收起来,我必须要去解决,但解决的办法已经不能在webpack上使劲了,因为ta真的爱莫能助,都没到ta那,不好伸手的,怎么办呢?


这个时候就想起了gulp

gulp是啥,用官方的话说

gulp 将开发流程中让人痛苦或耗时的任务自动化,从而减少你所浪费的时间、创造更大价值

em~~~定位很清晰,排解苦闷用的。

安装

安装 gulp,作为开发时依赖项

    yarn add -D gulp-cli
    //或
    npm install -D gulp gulp-cli

安装 gulp 命令行工具

    yarn add -g gulp-cli
    //或
    npm install -g gulp-cli

配置gulp

在项目根目录下,创建文件gulpfile.js,其在运行 gulp 命令时会被自动加载,在这个文件中我们写一下gulp的任务task

任务task

任务主要分为两种:

  • 公开任务(Public tasks) 从 gulpfile 中被导出(export),可以通过 gulp 命令直接调用。
  • 私有任务(Private tasks) 被设计为在内部使用,通常作为 series() 或 parallel() 组合的组成部分。

任务的执行有可以分同步和异步:

  • series是同步,如series(task1,task2, task3)
  • parallel是异步,如parallel(task1,task2, task3)

先贴出本文相关代码,然后再分析:

    /* gulpfile.js */
    ...
    var del = require('del');
    function cleanGame(cb) {
    return del([
        'build/web-mobile',
    ]).then(() => {
            cb()
            process.exit();
        });
    }
    ...
    exports.cleanGame = cleanGame;
    ...

分析

该方式并没有借助插件,官网推荐就是只有在转换文件时用插件,其他操作都应该使用(非插件的) Node 模块或库。
原文如下:

Plugins should always transform files. Use a (non-plugin) Node module or library for any other operations.

这里强调一点,这里引入的del可不是Node的模块,ta是,但是你并不用手动安装ta。
为什么?
别问,问就是我徒手一点一点分析依赖找出来的😂。

我从一堆依赖中,翻找出的关键信息如下:

...
webpack-dev-server:
  ...
  dependencies:
    ...
    del "^4.1.1"
    ...
...

webpack-dev-server已经自带了这个依赖,所以也就不用手动安装就可以引入了,可别错误的认为是Node模块奥。

del使用上也很简单,传入一个数组,其放入匹配的path,或是文件或是文件夹都行,可以动手试一下,然后ta会被返回一个Promise实例。你可以通过.then的方式去执行回调,其中回调函数中分别执行了两个函数:

  • cb():由于我们并没有返回一个stream流,所以我们需要手动的执行这个传入cb,以告知整个gulp流程该处理已经结束。可以看下stackoverflow的问题,其中这一段说的就很清楚:

    By returning a stream, the task system is able to plan the execution of those streams. But sometimes, especially when you’re in callback hell or calling some streamless plugin, you aren’t able to return a stream. That’s what the callback is for. To let the task system know that you’re finished and to move on to the next call in the execution chain.

  • process.exit();退出命令进程,exit的参数是code不传默认为0,表示成功,执行这句话,就是希望能够结束的时候自动的退出进程,省的我手动结束终端😁。

这里必须强调:ta俩执行顺序不能反了,要不会报错的。

[08:32:38] The following tasks did not complete: cleanGame
[08:32:38] Did you forget to signal async completion?

配置启动脚本

执行的命令很简单,直接执行:

    gulp cleanGame

然后在package.json中配置一下脚本命令,方便使用和集成。

    "scripts": {
        ...
        "cleanGame": "gulp cleanGame",
        ...
      }

至此gulp的基本配置ok了👌,通过该命令就能直接的讲游戏包🎮在打包之后去掉,而gulp如何做到整合命令,优雅的全自动化,我觉得有必要单独的写一篇,好好说说。

结语

gulp往往会在wabpack不方便的情况给予帮助,二者高低搭配,也恰恰呼应了Moderate的主张,中庸兼容,保中守和。

项目源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值