美文网首页
使用FIS3解决seajs中模块的路径匹配问题

使用FIS3解决seajs中模块的路径匹配问题

作者: caiminghan | 来源:发表于2018-10-10 20:16 被阅读0次

最近使用seajs开发的时候遇到一些问题,在此记录一下分享给大家。

模块定义

遵循seajs规范,模块化的js需要使用define函数定义,一个js文件即一个模块。define(id, deps, factory) 函数包括三个参数:iddeps、factory,其中id是模块的id,deps是模块的依赖。

模块ID定义

一般我们用js文件的路径来定义模块,如下:

define('src/mod1/demo', function(require, exports, module) {
  ...
});

在页面引入模块的时候使用seajs.use函数,需要使用模块的 id 引入模块,如下:

seajs.use(['src/mod1/demo'],function (demo) {
    ...
});

此时不得不说seajs中的模块路径规则,seajs要求模块的ID与路径匹配。 如果 seajs.userequire 引用的是不具名模块(未定义了 ID 的模块),则只需要填入模块文件的相对路径即可。 但是如果是引用具名模块(定义了 ID 的模块),会把 ID 和 seajs.use 函数中引用的路径名进行匹配,如果一致,则正确执行模块返回结果。反之,则返回 null。所以,如果想要定义模块的ID,最好与其绝对路径保持一致。
如果想随意定义模块ID,可以在页面中单独用<script>标签引入该模块文件,也可以通过seajs.use函数引入模块,但是这样做违背了seajs按需加载的机制,让js模块化失去意义。

模块间依赖注入

模块之间可以相互依赖,deps是模块的依赖,在deps中添加模块的ID,在加载模块之前会预先加载deps中的资源。如果define函数中deps参数为空,则在该模块被加载之前,会把整个js文件toString,解析为字符串后通过正则匹配,将所有的require()函数中的模块ID以String形式取出来,预先加载资源。
所以当deps参数为空时,不管require()函数出现何处(甚至是注释),都会被当做模块需要的资源预先加载。可想而知,此时require()也不可带变量,这样是获取不到资源的。

现针对上面的列举两种情况,逻辑一致,都是动态给 test2 赋值,但是得到结果却不一致。
1)第一种情况如下,会预先加载./mod1/test1.js./mod1/test2.js./mod2/test2.js。得到的test2为./mod1/test2'

define(function(require, exports, module) {
  'use strict'

  var test1 = require('./mod1/test1')
  var test2

  if(test1){
        test2 = require('./mod1/test2')
  }else{
        test2 = require('./mod2/test2')
  }
 ...
});

2)第二种情况如下,只会预先加载./mod1/test1.js,故得到的test2为null

define(function(require, exports, module) {
  'use strict'

  var test1 = require('./mod1/test1')
  var path

  if(test1){
        path = './mod1/test2'
  }else{
        path = './mod2/test2'
  }
  var test2 = require(path)
  ...
});

使用seajs-combo进行js资源合并

在前端工程中,经常会将前端资源合并,从而达到减少HTTP请求而提升前端性能。seajs也支持资源合并,使用 seajs-combo 插件,配合服务器的 nginx-http-concat 服务,可自动对同一批次的多个模块进行合并下载。
使用combo把模块化的js合并起来,要求每一个模块必须定义ID,遵循路径即ID的原则。
虽然seajs的规范比较简单且容易遵循,但是在一个前端工程中,往往开发环境的文件路径,和经过打包之后的实际环境的文件路径,不一定是一致的。
注意:combo功能需要配合nginx使用

使用FIS3进行打包

FIS3官网是这样介绍:FIS3 是面向前端的工程构建工具。解决前端工程中性能优化、资源加载(异步、同步、按需、预加载、依赖管理、合并、内嵌)、模块化开发、自动化工具、开发规范、代码部署等问题。
个人简单理解为一款前端打包工具。
FIS3支持cmd的模块化开发,帮我们解决模块路径的问题,使用我们在开发过程中不需再考虑头疼的路径问题,也可以完美的结合combo插件进行前端资源合并。安装FIS3参考官网,cmd插件参考使用文档

fis-conf.js配置文件

安装完FIS3和fis3-hook-cmd后,在工程根目录下创建FIS3配置文件fis-conf.js

project
│   fis-conf.js
│   index.html
│   ...
│
└─── src
│   │   
│   └─── mod1
│   │    │   test1.js
│   │    │   test2.js
│   │    │   ...
│   │
│   └─── mod2
│   │    │   test3.js
│   │    │   test4.js
│   │    │   ...
│   │
│   └─── ...
│       
└─── ...

关于FIS3配置文件,需要注意标明那些文件是模块化的js文件

fis.match('/src/**.js', { // 需要对目标文件设置 isMod 属性,说明这些文件是模块化代码。
  isMod: true
})

fis.hook('cmd', {
  baseUrl: '.' // 默认为 . 即项目根目录。用来配置模块查找根目录。
})

在更目录下打开命令行,使用FIS3打包代码,可参考FIS3命令

fis3 release -d ./dist

下图为index.html打包前后的对比,可以看到打包前seajs.use中模块ID写为相对路径,而打包之后变为绝对路径。


index.html.jpg

下图为demo.js打包前后的对比,可以看到打包前模块ID和模块依赖未定义,require()函数中路径为相对路径。打包之后,模块ID被定义为文件的绝对路径,原文件中require函数中的资源ID也变为绝对路径,并且通过deps形式注入依赖。


demo.js.jpg
可见,经过FIS3打包后,define函数中自动填入id,deps参数,即模块ID和模块依赖;引用js时,相对路径被替换为绝对路径。

相关文章

  • 使用FIS3解决seajs中模块的路径匹配问题

    最近使用seajs开发的时候遇到一些问题,在此记录一下分享给大家。 模块定义 遵循seajs规范,模块化的js需要...

  • SeaJS

    安装与使用通过npm install seajs安装 使用步骤: 引入seajs文件 定义主模块文件 主模块文件通...

  • Python3 - 文件路径名的操作

    问题 使用路径名来获取文件名,目录名,绝对路径等等。 解决方案 使用 os.path 模块中的函数来操作路径名。 ...

  • 文件路径名的操作

    问题 你需要使用路径名来获取文件名,目录名,绝对路径等等。 解决方案 使用 os.path 模块中的函数来操作路径...

  • javascript模块化编程-如何使用seajs和requir

    javascript模块化编程是什么? 公司在用seajs管理模块,怎么使用? seajs那么久都没有更新了,我...

  • seaJS模块化

    seaJS模块化 seajs.use('./init', function(init) {}); // 初始化模块...

  • CMD模块化开发

    SeaJS 是一个适用于 Web 浏览器端的模块加载器。使用 SeaJS,可以更好地组织 JavaScript 代...

  • Java使用File.separator解决Win和Linux的

    [linux和windows 中 File.separator代替 / 解决路径问题] Windows 使用 ...

  • 2.系统模块上

    time时间模块 datetime模块 随机模块random demo: 取随机验证码 解决路径引用问题 os模...

  • Python-模块

    模块 模块的搜索路径 模块导入的执行流程 循环导入 包 包中模块的使用:import 包的嵌套 包中模块的使用:f...

网友评论

      本文标题:使用FIS3解决seajs中模块的路径匹配问题

      本文链接:https://www.haomeiwen.com/subject/gnruvftx.html