sewing-kit-of-lemons v1.0.1
Sewing Kit
- Zero configuration: bootstrap, build, and deploy projects without a dedicated FED
- High performance: fast development flow, and optimized production deployments
- Organization scale: new knowledge, tools, and optimizations are available via a single update
Project Information
- #sewing-kit in Slack
- Unicorn project board
When can I use sewing-kit?
Standalone projects can use sewing-kit, but please read Caveats before jumping in.
When can I use sewing-kit in shopify/shopify
?
New sewing-kit projects in core are on hold until the web
project ships. Visit the web
project board to track its progress.
Message @lemonmade
in Slack to discuss the suitability of your project in core bundle.
Caveats & Roadmap
Rails Server Side Rendering (a.k.a. SSR, isomorphic apps, universal apps)
An Apps team is evaluating SSR for React/Rails projects. This investigation's findings will be integrated back into sewing_kit
.
TODO: link to Apps Unicorn project board. TODO: estimated date of completion.
Node Server Side Rendering
Currently, each app has to provide its own middleware setup. Use web
's Koa setup as a reference point. Common patterns will be integrated back into sewing-kit.
TODO: estimated date of common Node server middleware.
Can I use npm?
Yarn is the officially supported package manager. A modern version of npm with a package-lock.json
may work, but is not guaranteed to stay working.
Building libraries
sewing-kit's current focus is on building web applications. The long term roadmap includes Rollup support. In the meantime, sewing-kit is only useful for linting in library projects.
Project Layout (Rails)
See the rails_sewing_kit_example
repository for a live example.
Minimal Layout
├── Gemfile (must contain "gem 'sewing_kit'")
├── package.json (must specify '@shopify/sewing-kit' in 'devDependencies')
│
└── app
└── ui
└─- index.js
Rails / Polaris / React Layout
A typical Polaris app will use React to render views and components. The following layout shows best practice locations for:
- Global SCSS settings
- App sections (roughly analogous to Rails routes)
- Components
- Co-located CSS modules
- Co-located unit tests
├── package.json (must specify dependencies: `@shopify/polaris`, `react`, `react-dom`, and `sewing-kit`)
│─- config
│ └── sewing-kit.config.js (advanced configuration)
│
└── app
└── ui
├─- index.js (renders React into the DOM)
├── styles (optional)
│ └── settings.scss (global vars and @polaris overrides)
│
├-─ foundation (optional; base components for one use app concern things)
│ ├── App (base entry component for the app)
│ │ ├── index.js
│ │ ├── App.js
│ │ └── tests
│ │ └── App.test.js
│ │
│ └── index.js (export all foundation compoments)
│
├-─ sections (optional; container views that compose presentation components into UI blocks; usually map closely to 1st level route in the app)
│ ├── Home
│ │ ├-─ index.js
│ │ └── Home.js
│ │
│ └── index.js (export all sections)
│
└── components (optional)
│
├-─ MyComponent
│ ├-─ index.js
│ ├-─ MyComponent.js
│ ├── MyComponent.scss (optional; component-scoped CSS styles, mixins, etc)
│ └── tests
│ └── MyComponent.test.js
│
└── index.js (export all compoments)
Rails Helpers
<script>
tags
By default, app/ui/index.js
compiles into a main
bundle. The sewing_kit_script_tag
helper generates <script>
tags in .erb
files:
<%= sewing_kit_script_tag *sewing_kit_assets('main'), integrity: true %>
CSS <link>
tags
By default, CSS compiles into a main
CSS bundle. The sewing_kit_link_tag
helper generates <link>
in .erb
files:
<%= sewing_kit_link_tag *sewing_kit_assets('main', extension: 'css'), integrity: true %>
Project Layout (Node)
A typical configuration will contain server and client entry points as well as a routes file to share between them.
├── package.json
├── app
│ └── index.js (defines everything necessary for both server and client contexts: components, routes, queries, etc)
├── client
│ ├── index.js (imports and renders application for the client)
├── server
│ └── index.js (sets up the server process and any necessary middleware)
CSS Modules
To use CSS Modules in a component create a file in the component's directory like Component.scss
then import it:
import * as styles from './Component.scss';
export default function Component() {
return (
<div className={styles.Component} />
foobar
</div>
);
}
To guarantee modular CSS, classnames in your components will be obfuscated. This allows looser coupling between dependencies and stops users of your component from writing CSS that cares about non-API implementation details. This embodies our principle of API over implementation.
Instead of overriding CSS styles by targeting classnames inside other components, consider one of the following:
- adding an explicit API to cover your usecase
- creating a wrapping layout component
- building a new component entirely tailored to your usecase
TODO: document conventions: root element, variants, etc (point at web
docs?)
Component Conventions
TODO: point at web
docs?
Usage Guide
Help!
Embedded help for all commands is available via the --help
option:
$ yarn run sewing-kit build --help
Options:
--help Show help [boolean]
--mode [choices: "development", "production", "staging", "test"] [default: "production"]
--report [boolean] [default: false]
--source-maps [choices: "accurate", "fast", "off"] [default: "fast"]
Commands
See the full list of commands.
Scripting Commands
Add sewing-kit commands to your package.json
, e.g.:
{
"scripts": {
"build:development": "sewing-kit build --mode development",
"build:production": "sewing-kit build",
"check": "sewing-kit check",
"dev": "sewing-kit dev",
"lint": "sewing-kit lint",
"nuke": "sewing-kit nuke",
"optimize": "sewing-kit optimize",
"test": "sewing-kit test"
}
}
Then call them from the CLI, or dev.yml
using:
yarn run build:development
Building Bundle Reports/Viewing Bundle Contents
yarn sewing-kit build --report && open public/bundles/bundle-analysis/report.html
will build a bundle analysis which modules are part of each bundle, file sizes and sub-dependencies.
Configuration
Defaults
Small projects require no configuration when following the standard layout:
- Development mode information will be read from a project's
railgun.yml
- Production features (CDN, minification, code splitting, long term caching, etc) are provided with sane
shopifycloud
app defaults
Configuration Files
sewing-kit reads configuration from the following locations:
./config/sewing-kit.config.ts
(Rails only, iftypescript
is a project dependency)./config/sewing-kit.config.js
(Rails only)./sewing-kit.config.ts
(iftypescript
is a project dependency)./sewing-kit.config.js
(for JavaScript projects)
Configuration files must export a single function that generates a configuration.
Minimal Configuration
module.exports = function() {
return {};
};
Configuration with Plugins
A configuration function's plugins
argument contains a variety of plugins. Each plugins
method customizes/extends sewing-kit's behaviour.
e.g.: to omit jquery
from generated code, and instead read it from the window
object:
module.exports = function(plugins) {
return {
plugins: [plugins.externals({jquery: 'window.$'})],
};
};
Plugins
Configuration for Development/Production
An env
argument is also provided, allowing tuning for specific environments.
e.g., setting up a non-standard production CDN path:
module.exports = function(plugins, env) {
return {
plugins: [
plugins.cdn(
env.isProduction ? '//foo.shopifycloud.com/custom-path' : undefined, // Uses development defaults.
),
],
};
};
Available env
methods are:
hasProductionAssets
isDevelopment
isNotDevelopment
isClient
isTest
isCI
isDevelopmentClient
isTestClient
isServer
isDevelopmentServer
isTestServer
Custom Configuration Path
All commands accept a --config
directive that supersedes the default locations, e.g.:
sewing-kit build --config my/custom/config.js
This forces sewing-kit to read from my/custom/config.js
.
Using Preact
If you are building a smaller app that does not require all the React's functionalities and want to use Preact instead, you can now do it via sewing-kit.
Simply add preact
as a dependency instead of react
and react-dom
. This will add the proper configuration to use Preact with the h
pragma.
Example :
import {h, render, Component} from 'preact';
class MyComponent extends Component {
render(props, state) {
return <span>My preact component</span>;
}
}
render(<MyComponent />, document.body);
preact-compat
If you already have a React app, but want to use Preact to reduce your bundle size, you can use the preact-compat
. Adding the dependency will add the proper aliases to webpack, making it very easy to port your react app to Preact.
All you need to do is add preact
and preact-compat
to your dependencies and remove react
and react-dom
.
Note : Preact is not currently compatible with enzyme. There is a compatibility mode that is being developped for enzyme, but it does not currently fully support the different types of events.
TODO:
- Adding TypeScript, and TypeScript examples
- Adding GraphQL
- Adding React
- Adding Polaris
- Troubleshooting (restart your server on branch switch, sewing-kit nuke, dev up, #sewing-kit)
- Importing page-level CSS
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago