Skip to content

Instantly share code, notes, and snippets.

@muraray
Last active September 7, 2018 09:52
Show Gist options
  • Save muraray/d22d27999739d54ab66dd266b4b38bea to your computer and use it in GitHub Desktop.
Save muraray/d22d27999739d54ab66dd266b4b38bea to your computer and use it in GitHub Desktop.
Fabric React Rollup Boilerplate
# Boilerplate structure for React TypeScript and Rollup
A boilerplate to develop react apps and components with TypeScript and Rollup
## Getting Started
```bash
npm init -y
```
# Install dependencies
```bash
npm install -D --save-dev @types/react @types/react-dom rollup react react-dom
npm install -D --save-dev rollup-plugin-babili rollup-plugin-commonjs rollup-plugin-css-only rollup-plugin-livereload rollup-plugin-node-resolve rollup-plugin-postcss rollup-plugin-replace rollup-plugin-serve rollup-plugin-typescript2 rollup-watch
npm install -D --save-dev tslib tslint typescript typings
```
For Fabric inclusion
```bash
npm install -D --save-dev office-ui-fabric-react
```
# Prepare a sample react typescript file
mkdir src dist
touch ./dist/index.html
touch ./src/index.tsx
# Configuring the rollup, typescript, and linting
touch rollup.config.js
touch tsconfig.json
touch tslint.json
# Please do ensure all the above were created and configured as accordingly, have attached those file details in the trail gist for your reference.
# Ready to shoot the application
npm run watch
open http://localhost:3000/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Fabric React Rollup Typescript Bootstrap</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
import * as React from 'react';
import * as ReactDom from 'react-dom';
interface HelloProps {
compiler: string;
framework: string;
}
const Hello = (props: HelloProps) => (<div><h1>Hello from {props.compiler} and {props.framework}!</h1></div>);
ReactDom.render(
<Hello compiler="typescript" framework="react" />,
document.getElementById('app'),
);
/* For Fabric testing */
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Label } from 'office-ui-fabric-react/lib/Label';
import { CompoundButton, IButtonProps } from 'office-ui-fabric-react/lib/Button';
class App extends React.Component<IButtonProps> {
public constructor(props: {}) {
super(props);
}
public render(): JSX.Element {
const { disabled, checked } = this.props;
return (
<div>
<div>
<Label>Standard</Label>
<CompoundButton secondaryText="You can create a new account here." disabled={disabled} checked={checked}>
Create account
</CompoundButton>
</div>
<div>
<Label>Primary</Label>
<CompoundButton
primary={true}
secondaryText="You can create a new account here."
disabled={disabled}
checked={checked}
>
Create account
</CompoundButton>
</div>
</div>
);
}
}
ReactDom.render(
<App />,
document.getElementById('app'),
);
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "npm run lint && NODE_ENV=production rollup -c",
"watch": "rollup -cw",
"start": "rollup -cw",
"lint": "tslint --project tsconfig.json --type-check"
},
"devDependencies": {
"@types/react": "^16.4.11",
"@types/react-dom": "^16.0.7",
"autoprefixer": "^8.0.0",
"office-ui-fabric-react": "^6.55.0",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"rollup": "^0.65.0",
"rollup-plugin-babili": "^3.1.1",
"rollup-plugin-commonjs": "^9.1.6",
"rollup-plugin-css-only": "^0.4.0",
"rollup-plugin-livereload": "^0.6.0",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-postcss": "^1.6.2",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-serve": "^0.4.2",
"rollup-plugin-typescript2": "^0.16.1",
"rollup-watch": "^4.3.1",
"tslib": "^1.9.3",
"tslint": "^5.11.0",
"typescript": "^3.0.1",
"typings": "^2.1.1"
}
//import typescript from 'typescript';
import typescript from 'rollup-plugin-typescript2';
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import replace from 'rollup-plugin-replace';
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
import postcss from 'rollup-plugin-postcss';
import autoprefixer from 'autoprefixer';
import babili from 'rollup-plugin-babili';
const dev = 'development';
const prod = 'production';
const nodeEnv = parseNodeEnv(process.env.NODE_ENV);
const plugins = [
replace({
// The react sources include a reference to process.env.NODE_ENV so we need to replace it here with the actual value
'process.env.NODE_ENV': JSON.stringify(nodeEnv),
}),
// nodeResolve makes rollup look for dependencies in the node_modules directory
nodeResolve(),
commonjs({
// All of our own sources will be ES6 modules, so only node_modules need to be resolved with cjs
include: 'node_modules/**',
namedExports: {
// The commonjs plugin can't figure out the exports of some modules, so if rollup gives warnings like:
// ⚠️ 'render' is not exported by 'node_modules/react-dom/index.js'
// Just add the mentioned file / export here
'node_modules/react-dom/index.js': [
'render'
],
'node_modules/react/index.js': [
'Component',
'PropTypes',
'createElement',
]
},
}),
postcss({
extract: true, // extracts to `${basename(dest)}.css`
plugins: [autoprefixer],
writeDefinitions: true,
// postcssModulesOptions: { ... }
}),
typescript()
/*
typescriptPlugin({
// The current rollup-plugin-typescript includes an old version of typescript, so we import and pass our own version
typescript,
// rollup-plugin-typescript will inject some typescript helpers to your files (normally tsc will
// do this). They however have some ES6 keywords like const so they break older browsers.
// This instructs rollup-plugin-typescript to import tslib instead, which includes the same helpers
// in proper format.
importHelpers: true,
}),*/
];
if (nodeEnv === dev) {
// For playing around with just frontend code the serve plugin is pretty nice.
// We removed it when we started doing actual backend work.
plugins.push(serve({
port: 3000,
verbose: true,
contentBase: './dist'
}));
//plugins.push(serve('./dist'));
plugins.push(livereload({ watch: 'dist' }));
}
if (nodeEnv === prod) {
plugins.push(babili({ comments: false }));
}
export default {
plugins,
input: './src/index.tsx',
output: {
sourcemap: nodeEnv === dev ? true : false,
file: './dist/bundle.js',
format: 'iife'
}
};
function parseNodeEnv(nodeEnv) {
if (nodeEnv === prod || nodeEnv === dev) {
return nodeEnv;
}
return dev;
}
{
"compilerOptions": {
"jsx": "react",
"module": "es2015",
"target": "es2017",
"moduleResolution": "node",
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"strictNullChecks": true,
"sourceMap": true
},
"include": [
"src/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
{
"rules": {
"no-internal-module": true,
"no-reference": true,
"no-var-requires": true,
"prefer-for-of": true,
"ban-types": {
"options": [
["Object", "Avoid using the `Object` type. Did you mean `object`?"],
["Function", "Avoid using the `Function` type. Prefer a specific function type, like `() => void`, or use `ts.AnyFunction`."],
["Boolean", "Avoid using the `Boolean` type. Did you mean `boolean`?"],
["Number", "Avoid using the `Number` type. Did you mean `number`?"],
["String", "Avoid using the `String` type. Did you mean `string`?"]
]
},
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
],
"unified-signatures": true,
"curly": true,
"no-arg": true,
"no-conditional-assignment": true,
"no-empty": true,
"no-eval": true,
"no-for-in-array": true,
"no-inferred-empty-object-type": true,
"no-null-keyword": true,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-unsafe-finally": true,
"no-unused-expression": true,
/*"no-unused-new": true,*/
"no-var-keyword": true,
"no-void-expression": false,
"radix": true,
"restrict-plus-operands": true,
"triple-equals": true,
/*"typeof-compare": true,*/
"use-isnan": true,
"eofline": true,
"indent": [true, "spaces"],
"no-default-export": false,
"no-mergeable-namespace": true,
"no-trailing-whitespace": true,
"prefer-const": true,
"trailing-comma": [true, { "multiline": "always", "singleline": "never" }],
"arrow-parens": false,
"callable-types": true,
"class-name": true,
"interface-over-type-literal": true,
"new-parens": true,
"no-angle-bracket-type-assertion": true,
"no-consecutive-blank-lines": true,
"no-parameter-properties": true,
"object-literal-key-quotes": [true, "as-needed"],
"object-literal-shorthand": true,
"one-line": [true, "check-catch", "check-finally", /*"check-else",*/ "check-open-brace", "check-whitespace"],
"one-variable-per-declaration": true,
"quotemark": [true, "single", "jsx-double"],
"semicolon": [true, "always"],
"space-before-function-paren": [true, { "anonymous": "allow", "named": "allow", "asyncArrow": "always", "method": "allow", "constructor": "allow" }],
"variable-name": [true, "check-format", "allow-pascal-case", "allow-leading-underscore", "ban-keywords"],
"whitespace": [true, "check-branch", "check-decl", "check-operator", "check-module", "check-separator", "check-type", "check-typecast"]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment