四度空间

专注.NET、SharePoint

SharePoint Framework 在web部件中使用已存在的JavaScript库 - 捆绑打包和外部引用

博客地址:http://blog.csdn.net/FoxDave

在构建SPFx客户端web部件时,你可以使用公网已有的JavaScript库来构建强大的解决方案。但是在使用的时候你需要考虑你引用的东西没有影响SharePoint页面的性能。

以包的形式引用已存在的库

引用已存在的JavaScript库的通常方式是以包的形式安装到项目中。拿Angular举例,首先在项目中安装它的包:

npm install angular --save

接下来通过TypeScript使用Angular,需要安装类型:

npm install @types/angular --save

最后,在你的web部件中引用Angular,使用import声明:

import { Version } from '@microsoft/sp-core-library';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';

import styles from './HelloWorld.module.scss';
import * as strings from 'helloWorldStrings';
import { IHelloWorldWebPartProps } from './IHelloWorldWebPartProps';

import * as angular from 'angular';

export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
  public render(): void {
    this.domElement.innerHTML = `
      <div class="${styles.helloWorld}">
        <!-- omitted for brevity -->
      </div>`;

      angular.module('helloworld', []);

      angular.bootstrap(this.domElement, ['helloworld']);
  }

  // omitted for brevity
}
打包web部件资源

SPFx使用基于开源的工具链进行编译,如gulp和Webpack。在编译SPFx项目时,这些编译工具会在一个叫做bundling的进程中自动将所有引用的资源打包到一个单一的JavaScript文件中。这种方式有很多优点。首先,所有web部件需要的资源都在一个单一的JavaScript文件中可用。这简化了web部件的部署步骤,不容易产生遗漏。由于你的web部件使用了不同的资源,以正确的顺序逐个加载是很重要的。同时这种方式也对终端用户有益。一般来说,下载一个较大的单一文件要比下载好多小文件要快,进而你的web部件也会在页面上更快地完成加载。

然而这种方式也有一些不足。在编译SPFx中已存在的JavaScript框架时,所有引用的脚本都被包含在生成的单一文件中,以Angular为例,这个生成后的文件有170KB。


如果你在项目中再添加一个也使用Angular的web部件,在编译后你会发现有两个170KB的文件。这样当你在页面中同时添加这两个web部件的时候,就会加载两次同样内容的较大的脚本文件,这严重影响了性能。

作为外部资源引用已存在的库

一个更好的引用已存在的库的实现方式是作为外部资源进行引用。这样在web部件中就只有一个脚本的URL就够了,其实跟web页面的编写是一个意思,在页面加载的时候会自动去加载指定URL的资源。

这种方式也不需要进行包的安装,但是需要安装类型:

npm install @types/angular --save

接下来在config/config.json文件中的externals属性中加入一条:

"angular": {
  "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
  "globalName": "angular"
}
完整的文件内容大致如下所示:
{
  "entries": [
    {
      "entry": "./lib/webparts/helloWorld/HelloWorldWebPart.js",
      "manifest": "./src/webparts/helloWorld/HelloWorldWebPart.manifest.json",
      "outputPath": "./dist/hello-world.bundle.js"
    }
  ],
  "externals": {
    "angular": {
      "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
      "globalName": "angular"
    }
  },
  "localizedResources": {
    "helloWorldStrings": "webparts/helloWorld/loc/{locale}.js"
  }
}
最后,在你的web部件中引用Angular就可以了,跟之前没什么区别:

import { Version } from '@microsoft/sp-core-library';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';

import styles from './HelloWorld.module.scss';
import * as strings from 'helloWorldStrings';
import { IHelloWorldWebPartProps } from './IHelloWorldWebPartProps';

import * as angular from 'angular';

export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
  public render(): void {
    this.domElement.innerHTML = `
      <div class="${styles.helloWorld}">
        <!-- omitted for brevity -->
      </div>`;

      angular.module('helloworld', []);

      angular.bootstrap(this.domElement, ['helloworld']);
  }

  // omitted for brevity
}
再次编译你的项目你会发现这次的大小只有6KB。


如果你再添加一个web部件,那么就会生成两个大小为6KB的文件。说到这里大家可能会有疑问,这实际上就是大小变了而已,但是并没改变加载文件的数量。其实不是的,前一种方式是将要引用的库一起打包到了JS文件中,实际上相当于加载了两次;而对于外部引用这种方式,外部的资源如Angular只加载一次,并且得益于缓存机制,外部引用的资源很可能已经在用户访问你的web部件时加载好了,这么看确实是提高了性能。

posted on 2018-01-22 10:08  月飘冥  阅读(...)  评论(...编辑  收藏

My Links

Blog Stats