Initial release (#304)
This commit is contained in:
parent
f82957cc56
commit
352710fa93
|
@ -0,0 +1,25 @@
|
|||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# we recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[{package,bower}.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -0,0 +1 @@
|
|||
* text=auto
|
|
@ -0,0 +1,32 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
|
||||
# Build generated files
|
||||
dist
|
||||
lib
|
||||
solution
|
||||
temp
|
||||
*.sppkg
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Visual Studio files
|
||||
.ntvs_analysis.dat
|
||||
.vs
|
||||
bin
|
||||
obj
|
||||
|
||||
# Resx Generated Code
|
||||
*.resx.ts
|
||||
|
||||
# Styles Generated Code
|
||||
*.scss.ts
|
|
@ -0,0 +1,14 @@
|
|||
# Folders
|
||||
.vscode
|
||||
coverage
|
||||
node_modules
|
||||
sharepoint
|
||||
src
|
||||
temp
|
||||
|
||||
# Files
|
||||
*.csproj
|
||||
.git*
|
||||
.yo-rc.json
|
||||
gulpfile.js
|
||||
tsconfig.json
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"version": "1.1.3",
|
||||
"libraryName": "js-solution-editions",
|
||||
"libraryId": "d32a2713-6c4e-4b63-b1a3-b35698bf167b",
|
||||
"environment": "spo"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
# Handling Multiple Editions of SPFx Solution
|
||||
## Summary
|
||||
This sample shows possible approach of handling multiple editions (e.g. trial, lite, full) of SharePoint Framework solution.
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
![drop](https://img.shields.io/badge/drop-ga-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
* [SharePoint Framework](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
js-solution-editions | Alex Terentiev ([Sharepointalist Inc.](http://www.sharepointalist.com), [AJIXuMuK](https://github.com/AJIXuMuK))
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|August 23, 2017|Initial release
|
||||
|
||||
## Disclaimer
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
||||
## Description
|
||||
|
||||
### Use Case
|
||||
You are an ISV and developing some product that has multiple editions, let's say, trial, lite, full. You want to have separate package file (sppkg) for each edition and also reference different CDNs based on the edition.
|
||||
|
||||
### Problems to address
|
||||
Thinking about the use case in details we can point several problems that should be addressed:
|
||||
- When we're creating a new version we should create 3 separate sppkg files
|
||||
- Each sppkg file should contain manifest that references different CDN endpoints
|
||||
- It should be easy to upgrade customer from trial to lite and then to full; or directly from trial to full
|
||||
- You should know current edition in the code to execute the logic based on the edition's restrictions
|
||||
|
||||
### Approach
|
||||
This sample shows the approach that is based on custom Gulp task that should be run before bundling and packaging the solution.
|
||||
The name of the task is `change-build-edition`. Parameter: `edition`.
|
||||
The task updates SPFx solution configuration files to contain edition-specific information:
|
||||
- deploy-azure-storage.json is updated to contain correct `container` value
|
||||
- package-solution.json is updated to contain correct `solution.version` and `paths.zippedPackage` values. In this sample I'm using version's revision - 4th digit - to specify the edition: 0 for trial, 1 for lite, 2 for full. It allows to easily update customers. zippedPackage path is modified to create sppkg in subfolder based on edition configuration.
|
||||
- write-manifests.json is updated to contain correct CDN endpoint URL.
|
||||
|
||||
Additionally, web part's source code folder contains `custom-config.json` file with `edition` property:
|
||||
```
|
||||
{
|
||||
"edition": "full"
|
||||
}
|
||||
```
|
||||
This file is modified by custom task as well to contain correct edition.
|
||||
Later `custom-config.json` is referenced (`require('./custom-config.json')`) in web part code to provide custom logic based on current edition.
|
||||
|
||||
Use following commands to build specific edition version:
|
||||
```
|
||||
gulp change-build-edition --edition lite
|
||||
gulp bundle --ship
|
||||
gulp package-solution --ship
|
||||
gulp deploy-azure-storage
|
||||
```
|
||||
|
||||
## Resources
|
||||
[Handling Multiple Editions of SPFx Solution](http://tricky-sharepoint.blogspot.com/2017/08/handling-multiple-editions-of-spfx.html)
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"editions": [{
|
||||
"edition": "trial",
|
||||
"azureContainer": "js-solution-editions-trial",
|
||||
"cdnPath": "<!-- PATH TO CDN TRIAL -->",
|
||||
"revision": "0",
|
||||
"pkgPath": "solution/trail/js-solution-editions.sppkg"
|
||||
}, {
|
||||
"edition": "lite",
|
||||
"azureContainer": "js-solution-editions-lite",
|
||||
"cdnPath": "<!-- PATH TO CDN LITE -->",
|
||||
"revision": "1",
|
||||
"pkgPath": "solution/lite/js-solution-editions.sppkg"
|
||||
}, {
|
||||
"edition": "full",
|
||||
"azureContainer": "js-solution-editions-full",
|
||||
"cdnPath": "<!-- PATH TO CDN TRIAL -->",
|
||||
"revision": "2",
|
||||
"pkgPath": "solution/full/js-solution-editions.sppkg"
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"entries": [
|
||||
{
|
||||
"entry": "./lib/webparts/helloWorld/HelloWorldWebPart.js",
|
||||
"manifest": "./src/webparts/helloWorld/HelloWorldWebPart.manifest.json",
|
||||
"outputPath": "./dist/hello-world.bundle.js"
|
||||
}
|
||||
],
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"helloWorldStrings": "webparts/helloWorld/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"deployCdnPath": "temp/deploy"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"workingDir": "./temp/deploy/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "js-solution-editions",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"solution": {
|
||||
"name": "js-solution-editions-client-side-solution",
|
||||
"id": "d32a2713-6c4e-4b63-b1a3-b35698bf167b",
|
||||
"version": "1.0.0.1",
|
||||
"skipFeatureDeployment": true
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/js-solution-editions.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"port": 4321,
|
||||
"initialPage": "https://localhost:5432/workbench",
|
||||
"https": true,
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
// Display errors as warnings
|
||||
"displayAsWarning": true,
|
||||
// The TSLint task may have been configured with several custom lint rules
|
||||
// before this config file is read (for example lint rules from the tslint-microsoft-contrib
|
||||
// project). If true, this flag will deactivate any of these rules.
|
||||
"removeExistingRules": true,
|
||||
// When true, the TSLint task is configured with some default TSLint "rules.":
|
||||
"useDefaultConfigAsBase": false,
|
||||
// Since removeExistingRules=true and useDefaultConfigAsBase=false, there will be no lint rules
|
||||
// which are active, other than the list of rules below.
|
||||
"lintConfig": {
|
||||
// Opt-in to Lint rules which help to eliminate bugs in JavaScript
|
||||
"rules": {
|
||||
"class-name": false,
|
||||
"export-name": false,
|
||||
"forin": false,
|
||||
"label-position": false,
|
||||
"member-access": true,
|
||||
"no-arg": false,
|
||||
"no-console": false,
|
||||
"no-construct": false,
|
||||
"no-duplicate-case": true,
|
||||
"no-duplicate-variable": true,
|
||||
"no-eval": false,
|
||||
"no-function-expression": true,
|
||||
"no-internal-module": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-unnecessary-semicolons": true,
|
||||
"no-unused-expression": true,
|
||||
"no-unused-imports": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-with-statement": true,
|
||||
"semicolon": true,
|
||||
"trailing-comma": false,
|
||||
"typedef": false,
|
||||
"typedef-whitespace": false,
|
||||
"use-named-parameter": true,
|
||||
"valid-typeof": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const build = require('@microsoft/sp-build-web');
|
||||
|
||||
const logging = require('@microsoft/gulp-core-build');
|
||||
const fs = require('fs');
|
||||
|
||||
// path to editions config file
|
||||
const buildConfigFilePath = './config/build-config.json';
|
||||
// path to deploy-azure-storage.json
|
||||
const azureConfigFilePath = './config/deploy-azure-storage.json';
|
||||
// path to package-solution.json
|
||||
const solutionConfigFilePath = './config/package-solution.json';
|
||||
// path to write-manifests.json
|
||||
const manifestFilePath = './config/write-manifests.json';
|
||||
// path to custom-config.json that contains edition name to use in code
|
||||
const customConfigFilePath = './src/webparts/helloWorld/custom-config.json';
|
||||
|
||||
// adding custom task. Can be executed with gulp change-build-edition --edition lite
|
||||
build.task('change-build-edition', {
|
||||
execute: (config) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
// getting edition parameter
|
||||
const edition = config.args['edition'] || 'full';
|
||||
|
||||
// getting package-solution.json content
|
||||
const solutionJSON = JSON.parse(fs.readFileSync(solutionConfigFilePath));
|
||||
// getting deploy-azure-storage.json content
|
||||
const azureJSON = JSON.parse(fs.readFileSync(azureConfigFilePath));
|
||||
// getting write-manifests.json content
|
||||
const manifestJSON = JSON.parse(fs.readFileSync(manifestFilePath));
|
||||
// getting custom-config.json content
|
||||
const customConfigJSON = JSON.parse(fs.readFileSync(customConfigFilePath));
|
||||
// getting editions configurations
|
||||
const buildJSON = JSON.parse(fs.readFileSync(buildConfigFilePath));
|
||||
|
||||
// getting edition settings by edition name
|
||||
const editionInfo = getEditionInfo(buildJSON, edition);
|
||||
|
||||
if (!editionInfo) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
logging.log(`Configuring settings for edition: ${edition}`);
|
||||
|
||||
//
|
||||
// updating custom-config.json file
|
||||
//
|
||||
customConfigJSON.edition = edition;
|
||||
logging.log('Updating custom config for the web part...');
|
||||
fs.writeFileSync(customConfigFilePath, JSON.stringify(customConfigJSON));
|
||||
|
||||
//
|
||||
// updating package-solution.json
|
||||
//
|
||||
const revNumberStartIndex = solutionJSON.solution.version.lastIndexOf('.');
|
||||
// new version
|
||||
solutionJSON.solution.version = solutionJSON.solution.version.substring(0, revNumberStartIndex + 1) + editionInfo.revision;
|
||||
logging.log(`Checking if sppkg directory '${editionInfo.pkgPath}' exists and creating if not...`);
|
||||
// creating subfolder if doesn't exist
|
||||
ensurePath(editionInfo.pkgPath);
|
||||
// updating zippedPackage path
|
||||
solutionJSON.paths.zippedPackage = editionInfo.pkgPath;
|
||||
logging.log('Updating package-solution.json...');
|
||||
fs.writeFileSync(solutionConfigFilePath, JSON.stringify(solutionJSON));
|
||||
|
||||
//
|
||||
// updating deploy-azure-storage.json
|
||||
//
|
||||
azureJSON.container = editionInfo.azureContainer;
|
||||
logging.log('Updating deploy-azure-storage.json...');
|
||||
fs.writeFileSync(azureConfigFilePath, JSON.stringify(azureJSON));
|
||||
|
||||
//
|
||||
// updating write-manifests.json
|
||||
//
|
||||
manifestJSON.cdnBasePath = editionInfo.cdnPath;
|
||||
logging.log('Updating write-manifests.json...');
|
||||
fs.writeFileSync(manifestFilePath, JSON.stringify(manifestJSON));
|
||||
|
||||
resolve();
|
||||
}
|
||||
catch (ex) {
|
||||
logging.log(ex);
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets edition settings by name
|
||||
* @param {any} buildJSON editions settings
|
||||
* @param {string} edition edition name
|
||||
*/
|
||||
function getEditionInfo(buildJSON, edition) {
|
||||
edition = edition || 'full';
|
||||
let result = null;
|
||||
|
||||
if (buildJSON && buildJSON.editions && buildJSON.editions.length) {
|
||||
for (let i = 0, len = buildJSON.editions.length; i < len; i++) {
|
||||
const ver = buildJSON.editions[i];
|
||||
if (ver.edition === edition) {
|
||||
result = ver;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = {
|
||||
'edition': 'full',
|
||||
'azureContainer': 'js-solution-editions-full',
|
||||
'cdnPath': '<!-- PATH TO CDN FULL -->',
|
||||
'revision': '2',
|
||||
'pkgPath': 'solution/full/js-solution-editions.sppkg'
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the subfolders from the path exist
|
||||
* @param {string} path relative path to sppkg file (relative to ./sharepoint folder)
|
||||
*/
|
||||
function ensurePath(path) {
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
|
||||
let pathArray = path.split('/');
|
||||
if (!pathArray.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// removing filename from the path
|
||||
//
|
||||
if (pathArray[pathArray.length - 1].indexOf('.') !== -1) {
|
||||
pathArray.pop();
|
||||
}
|
||||
|
||||
//
|
||||
// adding sharepoint as a root folder
|
||||
//
|
||||
if (pathArray[0] !== 'sharepoint') {
|
||||
pathArray.unshift('sharepoint');
|
||||
}
|
||||
|
||||
//
|
||||
// creating all subfolders if needed
|
||||
//
|
||||
let currPath = '.';
|
||||
|
||||
for (let i = 0, length = pathArray.length; i < length; i++) {
|
||||
const pathPart = pathArray[i];
|
||||
currPath += `/${pathPart}`;
|
||||
|
||||
if (!fs.existsSync(currPath)) {
|
||||
fs.mkdir(currPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build.initialize(gulp);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "js-solution-editions",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-core-library": "~1.1.0",
|
||||
"@microsoft/sp-webpart-base": "~1.1.1",
|
||||
"@types/webpack-env": ">=1.12.1 <1.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "~1.1.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.1.1",
|
||||
"@microsoft/sp-webpart-workbench": "~1.1.0",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": ">=3.4.34 <3.6.0",
|
||||
"@types/mocha": ">=2.2.33 <2.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
.helloWorld {
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 0px auto;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
max-width: 715px;
|
||||
margin: 5px auto 5px auto;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.button {
|
||||
// Our button
|
||||
text-decoration: none;
|
||||
height: 32px;
|
||||
|
||||
// Primary Button
|
||||
min-width: 80px;
|
||||
background-color: #0078d7;
|
||||
border-color: #0078d7;
|
||||
color: #ffffff;
|
||||
|
||||
// Basic Button
|
||||
outline: transparent;
|
||||
position: relative;
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
border-width: 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
|
||||
.label {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
||||
|
||||
"id": "cfefc5ff-be4e-4cbf-bf58-ce98ee36c6fa",
|
||||
"alias": "HelloWorldWebPart",
|
||||
"componentType": "WebPart",
|
||||
|
||||
// The "*" signifies that the version should be taken from the package.json
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
|
||||
// If true, the component can only be installed on sites where Custom Script is allowed.
|
||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||
"requiresCustomScript": false,
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "cfefc5ff-be4e-4cbf-bf58-ce98ee36c6fa",
|
||||
"group": { "default": "Under Development" },
|
||||
"title": { "default": "HelloWorld" },
|
||||
"description": { "default": "HelloWorld description" },
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"description": "HelloWorld"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
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';
|
||||
|
||||
var config:any = require('./custom-config.json');
|
||||
|
||||
export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
|
||||
|
||||
public render(): void {
|
||||
this.domElement.innerHTML = `
|
||||
<div class="${styles.helloWorld}">
|
||||
<div class="${styles.container}">
|
||||
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
|
||||
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
|
||||
<span class="ms-font-xl ms-fontColor-white">Current edition:</span>
|
||||
<p class="ms-font-l ms-fontColor-white">${config.edition}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('description', {
|
||||
label: strings.DescriptionFieldLabel
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export interface IHelloWorldWebPartProps {
|
||||
description: string;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"edition": "full"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"DescriptionFieldLabel": "Description Field"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
declare interface IHelloWorldStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
DescriptionFieldLabel: string;
|
||||
}
|
||||
|
||||
declare module 'helloWorldStrings' {
|
||||
const strings: IHelloWorldStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/// <reference types="mocha" />
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
describe('HelloWorldWebPart', () => {
|
||||
it('should do something', () => {
|
||||
assert.ok(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "commonjs",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"es6-collections",
|
||||
"webpack-env"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// Type definitions for Microsoft ODSP projects
|
||||
// Project: ODSP
|
||||
|
||||
/* Global definition for UNIT_TEST builds
|
||||
Code that is wrapped inside an if(UNIT_TEST) {...}
|
||||
block will not be included in the final bundle when the
|
||||
--ship flag is specified */
|
||||
declare const UNIT_TEST: boolean;
|
||||
|
||||
/* Global defintion for SPO builds */
|
||||
declare const DATACENTER: boolean;
|
|
@ -0,0 +1 @@
|
|||
/// <reference path="@ms/odsp.d.ts" />
|
Loading…
Reference in New Issue