以下是关于前端项目模块化的实践,包含以下内容:

  1. 搭建 NPM 私有仓库管理源码及依赖
  2. 使用 Webpack 打包基础设施代码
  3. 使用 TypeScript 编写可靠类库

本文是关于前端项目模板化的第2部分

现状

实际项目远远比示例使用的 myGreeting 复杂,比如

  • 为了提高可维护性我们将项目折成了许多功能模板;
  • 我们希望使用 Promise 等语法等,但是顾忌目标环境的支持能力;
  • 可能依赖了多个第三方类库;
  • 为了提高加载速度我们打包时需要进行很多额外工作;
    • 代码压缩;
    • Tree Shaking(参考文末);
  • 既能运行在 WEB 浏览器,也能在 NodeJS 中使用;

假设我们有一个工具集项目 myHammer,包含 base64 转换功能和一个简单版的字典树实现,项目结构如下:

busybruce@DESKTOP-B8KJKRS /d/Documents/MyGit/PracticeInNPM/myHammer
$ tree src/ test/
src/
├── base64.js
├── index.js
└── TrieFilter.js
test/
├── base64.test.js
└── TrieFilter.test.js 0 directories, 5 files

index.js 导出了项目中的功能模块:

const base64     = require('./base64');
const TrieFilter = require('./TrieFilter') module.exports = {
base64,
TrieFilter,
}

如果不打包,单独发布当前项目到 NPM 仓库并没有问题,只是

  1. 依赖本项目的时候写法比较纠结,形如 const base64 = require('myHammer/src/base64')
  2. 可能存在到目标环境的适配问题,如前文所述;
  • 目标环境不支持 Promise 等语法等
  • 源码是 CoffeeScript 或者 TypeScript,没法直接引用

下面使用 Webpack 来解决这些问题。

Webpack 打包基础类库

Webpack 文档内容多,网上教程多是关于应用打包,现整理如下。

本文并非 Webpack 的使用指南,只提及类库打包,行文时Webpack已更新至4.x 版本。

package.json

需要配置 package.jsonmain 节点供 NodeJS 环境使用。

"main": "src/index.js",

NodeJS 运行环境作了约定,使用 require('xxx')时将读取该配置。

  1. 避免形如 require('myHammer/src/base64')类似的引用完整路径的写法
  2. 如果源码使用了高版本的语言特性,可以转译和打包代码到形如 dist/inde-es5.js 的路径,再修改该配置指向该文件以向下兼容
  3. 使用需要转译成 JavaScript 语言同理

在部分 IDE 时我们查找引用时,往往发现函数声明有好多处实现,原因就在于代码转译、打包成了很多份,如下图所示。

webpack.config.js

类库打包需要对 webpack.config.js 中的 output 进行配置,摘取如下:

output : {
library : "hammer",
libraryTarget: "umd",
globalObject : "this",
path : path.join(__dirname, "dist"),
filename : "hammer.js",
}

其他配置请自行阅读文档,完整内容见代码 webpack.config.js

如前文所述,在不考虑语言、版本、目标平台的差异的情况下,直接将源码发布到 NPM 仓库,再添加依赖和引用并无问题。在业务日益复杂的情况下,手写代码在实现层面直接消除这些差异是无比巨大的工作量,使用 Webpack 让我们更专注业务本身, Make life easier


发布到 NPM 和使用依赖

在完成了具体业务后,我们打包项目并发布到私有 NPM 仓库

webpack --mode development # 视具体需求
npm publish --registry http://ubuntu-17:4873 # --force

myDemo 项目中我们添加引用

yarn add myHammer --registry http://ubuntu-17:4873

修改 index.js 如下:

const myGreeting = require('myGreeting');
const {base64} = require('myHammer'); (function () {
let greeting = myGreeting('Rattz');
console.log(base64.encode(greeting));
})();

运行起来

$ node index.js
SGVsbG8gUmF0dHo=

关于 Tree Shaking

略微提及一下 Tree Shaking ,简单地说 Tree Shaking 通过不引用没有依赖的代码,能有效缩减打包后的文件大小。

举例来说,我们使用了 ES2016 的语法,希望最后编译在 ES2015 环境使用。这里有若干种可行方案,其中一种是

  • 使用 babel 全家桶包含 babel-cli, babel-core, babel-loader, babel-preset-env
  • 添加 .babelrc 文件写入内容 {"presets":["env"]};
  • 在入口代码的首行使用 require('babel-polyfill');

babel 进行语法转换,补丁文件进行对低版本 ES2015 的适配,该方案中 babel-polyfill 被完整引用, 打包完成后占用120k 左右大小,往往比业务代码还多。

Tree Shaking 即为解决该问题而来,比如某模板同时提供了加法和减法,而我们只依赖了加法方法,如果打包工具支持 Tree Shaking,就能在打包时剔除掉未使用的减法相关代码。

Webpack 提供了相关支持,见于 Tree Shaking - webpack

项目所使用源码已发布 github,jusfrw 原创

前端项目模块化的实践2:使用 Webpack 打包基础设施代码的更多相关文章

  1. 前端项目模块化的实践3:使用 TypeScript 的收益

    以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...

  2. 前端项目模块化的实践1:搭建 NPM 私有仓库管理源码及依赖

    以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...

  3. 前端(以Vue为例)webpack打包后dist文件包如何部署到django后台中

    由于现在前端使用的三大框架配合webpack可以实现快速打包,为部署到服务端提供了非常大的便利,那么在前端打包后,应该做些什么可以部署到django的后台中呢? 1.打包后文件包dist 进入到 di ...

  4. webpack打包es6代码

    1.简单描述一下es6的模块导入和导出的语法: //导出:export var aa = 10;export function demo(){} //不能写成:var aa = 10;export a ...

  5. 简要分析webpack打包后代码

    开门见山 1.打包单一模块 webpack.config.js module.exports = { entry:"./chunk1.js", output: { path: __ ...

  6. webpack打包样式代码去重

    一.问题描述 控制台审查样式,同一个样式被导入很多遍,每调用一次@import "common.less";打包时都会多出一份类似的样式代码. 二.问题分析 补上... 三.解决方 ...

  7. nodejs 前端项目编译时内存溢出问题的原因及解决方案

    现象描述 昨天用webpack打包Vue的项目时,node内存溢出而停止build项目,即是项目构建过程中频繁报内存溢出:FATAL ERROR: CALL_AND_RETRY_LAST Alloca ...

  8. 如何使用webpack打包项目

    webpack是前端开发中比较常用的打包工具之一,另外还有gulp,grunt.之前没有涉及过打包这块,这里介绍一下使用webpack打包的流程. Grunt和Gulp的工作方式是:在一个配置文件中, ...

  9. 如何使用webpack打包你的项目

    webpack是前端开发中比较常用的打包工具之一,另外还有gulp,grunt.之前没有涉及过打包这块,这里介绍一下使用webpack打包的流程. Grunt和Gulp的工作方式是:在一个配置文件中, ...

随机推荐

  1. 如何用SQL脚本在SQL Server Replication中创建合并复制,以及怎么创建分区合并复制

    假设我们要创建合并复制的发布端数据库是EFDemo其中有四张表,订阅端数据库是EFDemoSubscription,如下图所示: 首先创建发布端快照代理Sql agent job:"EFDe ...

  2. qt调用sql server存储过程并获取output参数

    最近新做的一个项目需要使用qt5连接另一台机器上的sql server,虽然网上已有类似文章,但还是有些其中很少提及的问题,故在这里汇总下: qt连接sql server可以参考这篇文章: <Q ...

  3. 团队作业7——第二次项目冲刺(Beta版本)day1

    项目成员:  曾海明(组长):201421122036 于波(组员):201421122058 蓝朝浩(组员):201421122048 王珏 (组员):201421122057 叶赐红(组员):20 ...

  4. EF CodeFirst 数据库的操作

    生成数据库 首先需要通过Nuget安装Migration 这一步是初始化Migration操作. 首先打开程序包控制台, 工具——NuGet包管理器——程序包管理控制台 打开后,在控制台输入下面的命令 ...

  5. 启动android monitor报错解决办法

    再这汇总一下这段时间使用android monitor新遇到的问题,特汇总对应问题解决办法如下: 1.确保JDK和Android studio位数相同,比如JDK使用的是64位,studio也要是64 ...

  6. postMessage 消息传递

    点击查看demo 前言 web开发了,除了前台与服务器交换数据,还有可能前台页面间需要进行数据传递,比如窗口间,页面和嵌套的iframe间.这些问题之前都有解决办法,但是现在html5引入的messa ...

  7. 洛谷P1208

    #include <iostream>#include <algorithm>#include <cstdio>using namespace std; struc ...

  8. docker swarm英文文档学习-6-添加节点到集群

    Join nodes to a swarm添加节点到集群 当你第一次创建集群时,你将单个Docker引擎置于集群模式中.为了充分利用群体模式,可以在集群中添加节点: 添加工作节点可以增加容量.当你将服 ...

  9. NodeHandles

    os::NodeHandle类有两个作用: 第一.它在roscpp程序内提供了一种RAII(Resource Acquisition Is Initialization)类型式启动和关闭内部节点的方法 ...

  10. Waymo在美国推出自动驾驶汽车共享服务

    导读 经过数月的测试和数百万英里的无人驾驶汽车技术开发,Waymo 正式在美国推出了具有商业性质的自动驾驶汽车的共享服务. 该公司的 Waymo One 项目将为客户提供 24 小时自动驾驶汽车服务. ...