Share via


Replace TypeScript with ES2015 for SharePoint Framework Applications

I am a huge fan of TypeScript. For large projects it is indispensable. However, most SharePoint Framework (SPFx) applications are not large by design. SharePoint Framework is intended for small, single purpose applications that augment the functionality of SharePoint. That is not to say that you will never write a SPFx application with 100,000+ lines of code, but applications of that are not common in the context of SPFx applications.

TypeScript comes with a cost. In my opinion the cost is worth it for large applications. The type safety will help you eliminate entire classes of bugs. However, this benefit comes with the cost of having to satisfy the compiler’s strict type checking for all of your code. With React applications, Props and State make this a bit more complicated.

For most SPFx applications, I prefer using es2015+ to build my React components. I don’t like fighting with the TypeScript compiler for the bite sized applications that SPFx was designed to build.

In this article, I will explain the steps to use es2015 or later to build SPFx applications.

There is no template for this, so we will use the React template that ships with the SPFx Yeoman generator. To get started create your application using:

 
mkdir my-project
cd my-project
yo @microsoft/sharepoint

You can accept all the defaults except for the question shown below. Choose React when asked “What framework would you like to use?”.

Next we need to add dependencies for Babel and friends to transpile our esNext code to JavaScript that most browsers can understand.

Go to a console window in the directory we created for our project and run the following command:

 
yarn add babel-loader babel-core babel-preset-env babel-preset-react babel-plugin-transform-class-properties -D

or with NPM:

 
npm i add babel-loader babel-core babel-preset-env babel-preset-react babel-plugin-transform-class-properties --save-dev

All of these dependencies, transpile our futuristic JavaScript. However, babel-plugin-transform-class-properties is used to make working with React easier. This is a proposed feature to the EcmaScript specification. It allows us to use class properties like this:

 
class MyComponent extends React.Component {
 handleSubmit = () => {
 // Code here
 }
}

With this syntax we can avoid cluttering the constructor with .bind(this) calls as arrow functions automatically set the “this” context to the enclosing class.

The webpack.config.js file is not exposed as part of the SPFx build process. However, an API is exposed that allows us to customize the build. We will leverage this from gulp. Add the following code to the gulpfile.js just above this line:

 
build.initialize(gulp);

The code to add:

 
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
 generatedConfiguration.module.rules.push(
 {
 test: /\.js$/,
 exclude: /(node_modules|bower_components)/,
 use: {
 loader: 'babel-loader',
 }
 });
 return generatedConfiguration;
}});

The above code merges a new configuration object into the Webpack config. However, we still need to provide some configuration to Babel. To do that we will use the package.json file.

Add the following code to package.json:

 
"babel": {
    "presets": [
        "env",
        "react"
    ],
    "plugins": [
        "babel-plugin-transform-class-properties"
    ]
},

I prefer to add it right under the “scripts” section and above the dependencies, but you can put it anywhere at the top level of the object.

At this point we need to convert the TypeScript application to JavaScript.

First rename all of the .ts or .tsx files to .js. Next, delete the “/app/components/IHelloWorldProps.ts” file and then delete the import statement for it in HelloWorldWebPart.js.

Next go through and delete all of the type annotations from the .js files you renamed previously. Also delete any import statements that pull in Props. After the above changes you should be able to run ‘gulp serve’ and at this point you should be able to create your components using es2015+ and have them compile and work correctly in the browser.