Friday, 1 July 2016

Understanding the web part manifest, bundle.json and other key files and folders in the SharePoint Framework

The new “SharePoint Framework” model for client web parts and client-side applications uses a whole series of files that developers must learn to successfully extend SharePoint using this approach. There is a new web part manifest file (now in JSON rather than XML) and files such as bundle.json, package-solution.json and upload-cdn.json which interact with the new Gulp-based developer tools to control how the solution is packaged and deployed – all wrapped up in a new folder structure. So, there’s a learning curve and understanding these files and folders is crucial. In the previous post Develop a client web part in the SharePoint Framework - a walk-through we looked at the overall “getting started” process which creates the files for you using Yeoman Generator – but in this article I’ll explain the files and folders.I

Folders used in the SharePoint Framework

Let’s start with a rundown of the various folders and what they contain. My last post had a cut-down version of this table, but I expand on the descriptions here, and add a list of key files and an image so you can see what that folder looks like:

Folder

Purpose

Key files

Image

src The place where you add/edit code files – you will build up your structure of files here.
  • [MyWebPart1.ts] (TypeScript)
  • [MyWebPart1.manifest.json]
SNAGHTML72de5c5_thumb
lib Contains “processed” code files which are ready to move into the bundle which is distributed with the app.

For example, TypeScript files have been compiled to JavaScript files in this directory.
  • [MyWebPart1].js
  • [MyWebPart2].js
SNAGHTML72e6ac4_thumb
dist Contains the final code files which are distributed with your application.

The most important file is the final JavaScript bundle file  [MyWebPart].bundle.js – this is all of the JS for your web part, including some framework stuff.
  • [MyWebPart].bundle.js
  • [MyWebPart].bundle.js.stats.json
  • webpart.manifest.js
SNAGHTML4ed93fd_thumb
config Contains a set of JSON files used by the tooling for the build process. In particular to control how your app is packaged - in terms of the .spapp file, JavaScript/CSS bundling and so on.
  • build.json
  • bundle.json
  • package-solution.json
  • serve.json
  • upload-cdn.json
SNAGHTML4e02bfb_thumb
node_modules Contains JavaScript modules used by the solution. TypeScript follows the standard set by node.js for resolving modules (i.e. when you use the import keyword to use an object defined in another module/library), and the node_modules folder is a key part of this.  Whatever JavaScript libraries your code OR the underlying SharePoint Framework has a dependency on. SNAGHTML73042df_thumb
typings Contains TypeScript typings files – these are used to give you auto-complete (IntelliSense) against JavaScript libraries you are using, such as jQuery. Typings for whatever JavaScript libraries you’re using in code. These typically get added with TypeScript Definition Manager with e.g.
tsd install jquery jqueryui --save
SNAGHTML14200135
sharepoint Contains the .spapp file which is generated by ‘gulp package-solution’. This is what you’ll add to the App Catalog of your real environments such as production.

Also has a ‘debug’ folder so you can see what went into the package.
  • [MyApp].spapp
SNAGHTML20029fca

The web part manifest

The [MyWebPart].manifest.json file is where core details such as the display name and description are specified. Critically, other associations are specified here such as the associated JavaScript file (usually a bundle) and any dependent JavaScript modules which will be loaded – yes, there’s an in-built JS loading framework for you. Here’s a rundown of some key properties specified in the manifest.json file:

Element

Sample value

Purpose

ManifestVersion 1 Represents the version of the manifest schema that the build system is expected. Currently this must be “1” – any other value will be rejected.
id 41d9c141-e10f-4373-8a24-84383fa95592 ID of the client web part – the same as we’re used to, i.e. it provides a concrete way of identifying a web part (e.g. through APIs)
bootstrapModule http://localhost:4321/dist/cob-latestnews-wp.bundle.js

https://cob.azureedge.net/intranet/cob-latestnews-wp.bundle.js
This is where the JS file for the web part lives. In dev, you’ll have a localhost path (which the tooling hosts for you using node.js). For production, you’ll replace this with the path where you deployed the JS file to for real – a CDN, website path, or similar.
moduleName CobLatestnewsWebPart JavaScript module name of the web part object.
localizedScripts ? I believe this is an array of locale/JavaScript file mappings – to support localization.
preloadModules

"preLoadModules": ["jquery","jqueryui"]

Specifies JavaScript modules that the web part should load before execution. The module names specified here must match names/paths specified in the “config” element described next – in other words, you name the module and specify where it’s loaded from.
config

"config": {
        "paths": {
            "jquery": "//code.jquery.com/jquery-1.10.2.js",
            "jqueryui": "//code.jquery.com/ui/1.11.4/jquery-ui.js"
        },
        "meta": {
            "jqueryui": {
                "scriptLoad": "true",
                "deps": [
                    "jquery"
                ]
            }
        }
    }

Used to specify paths to JavaScript libraries pre-loaded by the web part (as specified in the “preloadModules” tag). Dependencies between scripts are also specified here - so that jQuery is loaded before jQuery UI for example (shown left).
properties

"properties": {
    "description": "Displays recent docs for the current user.",
    "headerText": "Your recent documents:",
    "searchQuery": "*",
    "itemLimit": "5"
  }

Specifies default values for web part properties. Note that other elements of web part properties are defined in the web part code – specifically the interface which represents the web part’s properties, and the propertyPaneSettings method. You can see these in the code sample above.

Note that there are other properties in the manifest file which I’m not listing here – but these are some important ones for now!

Other key files in the “src” folder

In addition to the web part manifest, files your code files also live here. These other files here can be summarized more easily, so I’ll switch to bullet points. You will create sub-folders in here, and build our your codebase as you need. But let’s take the example of single web part, and look at the set of files used:

  • [MyWebPart].test.ts – a file to add Mocha JavaScript tests to
  • [MyWebPart].less – a file to add LESS CSS directives to. If you’re not familiar with LESS, it’s a way of structuring CSS in a neater way – it allows variables (e.g. @cob-title-color: #FFB900; – which you can then use in different styles). In addition to variables, CSS markup can be nested in a way which matches HTML structure. Both of these things make your CSS code easier to maintain.  See http://lesscss.org for more details.
  • [MyWebPart].strings.ts – a file to add resource strings to (to keep them in a separate place from your code, and therefore avoid magic strings)

Files in the “lib” folder

The lib folder serves as an intermediate folder in the build system. A few things happen between the src and lib folders:

  • TypeScript files get compiled to JavaScript files
  • LESS files get compiled to CSS files 
  • CSS files get minified, and prepared for the CSS loader
  • HTML templates files get compiled to JavaScript (N.B. I’m still working that one out!)
  • TypeScript typings files are generated for each of your .ts files (i.e. “foo.d.ts”, as per the TypeScript convention)

Files in the “dist” folder

These are files which are distributed with the app – several of these are used at run-time for example:

Key files:

  • [MyWebPart].bundle.js – this is all the JavaScript required to run your solution, and is CRUCIAL to your web part or client-side application working properly. When you package for production, you can host this file anywhere you like (CDN, Azure web app, on-premises web server etc.) but whatever URL it lives at must be reachable by end-users AND it must be specified in the “bootstrapModule” key in the web part manifest.
  • [MyWebPart].bundle.js.map – map file to support browser debugging
  • [MyWebPart].manifest.js – this is the shipped version of your web part manifest file.
  • [MyWebPart].bundle.js.stats.json – a file which contains metadata about the generated JS bundle. One really useful thing in here is the “modules” node, which lists all the original JavaScript files which went into the bundle. This is really useful if you’re troubleshooting why a JavaScript library you’re using isn’t making it’s way into the bundle (or vice-versa) – much easier than trying to read the uglified JavaScript in the bundle itself (and trying to work out where jQuery stops and jQuery UI starts for example!).

Files in the “config” folder

The config directory holds a collection of JSON files which mainly control how the app gets packaged. The most critical files are:

  • bundle.json – this controls which JavaScript files make their way into your final JS bundle. Note that by default, any 3rd party JS libraries you load as a module into your code (e.g. with something like import $ = require('jquery'))  will get included into the bundle. However, you can override this (for example if you’re referencing jQuery on a CDN) by adding an “exclude” entry with the same name. More on this in another article.
  • package-solution.json – controls the details of the app package which is produced by gulp package-solution. This is the .spapp file that you’d upload to the App Catalog to make the web part available when packaging for a non-dev environment
  • upload-cdn.json – I’m unsure if this will be in this form in the final toolchain at release time, but this file provides a convenient way to push files (e.g. your JavaScript bundle) to Azure file storage (and optionally Azure CDN, if you’ve configured that). The file takes parameters which identify your area in Azure BLOB storage so the files get uploaded to the right place, such as:
    • account
    • container
    • accessKey

Bundle.json is an important file, especially as you add multiple JavaScript files and reference more and more external libraries. I’ll dig deeper into this one in a future article, but for now let’s just consider a couple of key points. Here’s what bundle.json looks like in the current tooling:

The “entries” node specifies elements of your solution – for example each JavaScript file which should go into the bundle. Notably you can have 3rd party JavaScript libraries bundled in with your JS code if you like – in fact, you have to explicitly exclude them if you they are used as a module in your solution but you’re referencing a CDN at run-time for example. The key children of the “entries” element are:

Element

Sample value

Purpose

entry “./lib/webparts/cobLatestnewsWp/CobLatestnewsWpWebPart.js” Path to a source file to go into the JavaScript bundle. The “lib” folder is expected to contain JavaScript files, not TypeScript files – any TS files in the “src” folder are compiled to JavaScript files which are output here (think of gulp.dest() if you’re familiar with it).

However, it is not the final bundle of all JavaScript files - that is the one generated into the “dist” folder.
outputPath "./dist/cob-latestnews-wp.bundle.js" Path to the final JavaScript file for the entire bundle. This is what will be distributed with your app and what end-users will hit. 
exclude

"@ms/sp-client-platform",
  "jquery"

Modules used which should NOT go into the bundle (e.g. because you’re referencing jQuery [for example] on a CDN).

Files in the root folder

And finally, we get to files in the root folder. Several important files live here, such as gulpfile.js which is the entry point to the build system – you might choose to extend this to add custom Gulp tasks. The following list details the key files:

  • gulpfile.js – the “top” of the build system, and this defines the Gulp tasks you call from the command-line such as:
    • gulp build
    • gulp bundle
    • gulp serve
    • gulp package-solution
    • gulp upload-cdn
    • [N.B. the Gulp tasks themselves are defined within the node_modules\@ms\ms-core-build\tasks folder]
  • package.json – similar to “packages.config” in NuGet, in that it defines the JavaScript library dependencies (and their versions) used by your solution.
  • tsconfig.json – defines TypeScript compilation settings
  • tslint.json – defines TypeScript style checking settings

Summary

Phew! As you can see there are lots of new files and folders to get to grips with in the SharePoint Framework. Remember that this information is based on an early version of the Framework, and there may be some changes by the time things actually become generally available – I will update this post with any changes I find to keep the information accurate. I’ll also be covering more aspects of the SharePoint Framework in the next few articles.