tangle frontend
May 25, 2020
this post documents setting up the frontend portion of tangle
this post documents setting up the frontend portion of tangle.
This section covers the technical foundations including
- bootstrapping the lerna repo
- adding eslint and prettier
- setting up the frontend
bootstrap lerna repo
yarn init
yarn add lerna --dev
yarn lerna init
Add to package.json:
...
'name': 'root',
'private': true,
'workspaces': [
'packages/*'
]
...
Update lerna.json:
'packages': ['packages/*'],
'version': 'independent',
'npmClient': 'yarn',
'useWorkspaces': true
gitignore
eslint/prettier
Copy/paste eslint and prettier
yarn add babel-eslint eslint eslint-config-airbnb
eslint-config-prettier eslint-plugin-import
eslint-plugin-jsx-a11y eslint-plugin-prettier
eslint-plugin-react prettier -W -D
-W
for root flag
-D
for dev dependencies
Add to package.json
'lint': 'eslint --fix . && echo 'Lint complete.'',
Commit [init]
.
frontend / next.js
mkdir packages/web
npx create-next-app packages/web
Select Default starter app
Update name of web app to @tangle/web
Add command to root package.json
'web': 'lerna run --scope @tangle/web dev --stream'
commit [web] init
We want to share react and next across the codebase. Add these as devDependencies
to the root and add them as peerDependencies
in whatever packages need them.
component library
mkdir packages/components
cd packages/components && yarn init -y
Name package @tangle/components
.
Add peer dependencies
yarn workspace @tangle/components add -P react react-dom next
Add dependencies
yarn workspace @tangle/components add @emotion/styled @theme-ui/color styled-system theme-ui prop-types
Make a component
packages/components/src/components/Button/Button.js
import React from 'react';
import PropTypes from 'prop-types';
import styled from '@emotion/styled';
const StyledButton = styled.button`
color: red;
background-color: blue;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
Button.propTypes = {
/**
* content of button
*/
children: PropTypes.string
};
Button.defaultProps = {
children: null
};
export default Button;
Add storybook
yarn add -W -D @storybook/react @storybook/addon-actions
@storybook/addon-docs babel-loader @babel/core
Add .storybook
directory w/ config.js
and main.js
config.js
import { configure, addDecorator } from '@storybook/react';
addDecorator(storyFn => (storyFn()))
configure(require.context('../packages/components/src', true, /\.stories\.js$/), module);
main.js
module.exports = {
stories: ['../packages/**/*.stories.js'],
addons: ['@storybook/addon-docs']
};
Add a story for the button
Button.stories.js
import React from 'react';
import { action } from '@storybook/addon-actions';
import { storiesOf } from '@storybook/react';
import Button from './Button';
storiesOf('Button', module).add('default', () => (
<Button onClick={action('clicked')}>test</Button>
));
update root package.json
'stories': 'start-storybook'
Run storybook.
clean up and code share
babel-plugin-module-resolver helps us keep things looking clean.
yarn add -D -W babel-plugin-module-resolver eslint-plugin-import
eslint-import-resolver-babel-module eslint-import-resolver-alias
add a .babelrc
file
{
'plugins': [
['module-resolver', {
'root': ['./'],
'alias': {
'@components': './packages/components/src',
'@web': './packages/web'
}
}]
]
}
add to .eslintrc.js
settings: {
'import/resolver': {
'babel-module': {},
alias: {
map: [['@components', './packages/components/src']],
extensions: ['.ts', '.js', '.jsx', '.json']
}
}
}
add an index.js
file to components/src
and export the button component from there. Update the import in the Button.stories.js
file to reflect the update
import { Button } from '@components';
Run storybook to test.
Time to add the button to Next.js
Add a babel.config.js
to the next app
module.exports = {
babelrcRoots: ['../packages/*'],
presets: ['next/babel'],
plugins: [
[
'module-resolver',
{
root: ['./'],
alias: {
'@components': '../components/src'
}
}
]
]
};
We need to transpile the components as they come in:
yarn workspaces @tangle/web next-transpile-modules
Transpile components in the next.config.js
const withTM = require('next-transpile-modules')([
'../components/src'
]);
module.exports = withTM();
Call the Button
in your index to test. Run your next app.