1.0.1 • Published 5 years ago

sewing-kit-of-lemons v1.0.1

Weekly downloads
56
License
-
Repository
-
Last release
5 years ago

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

NPM version Build status

Project Information

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, if typescript is a project dependency)
  • ./config/sewing-kit.config.js (Rails only)
  • ./sewing-kit.config.ts (if typescript 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

See the full list of 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
@babel/core@shopify/async@shopify/browserslist-config@shopify/build-targets@shopify/fail-on-unexpected-module-shaking-plugin@shopify/find-duplicate-dependencies-plugin@shopify/images@shopify/polyfills@shopify/react-server-webpack-plugin@shopify/typescript-configs@shopify/webpack-asset-metadata-plugin@shopify/webpack-asset-sri-hash-verification-plugin@shopify/webpack-ignore-typescript-export-warnings-plugin@shopify/webpack-no-react-jsx-loader@shopify/webpack-no-typescript-ts-loader@shopify/webpack-persisted-graphql-plugin@shopify/webpack-react-loadable-plugin@shopify/webpack-runtime-sri-verification-plugin@shopify/webpack-section-focus-loader@svgr/webpack@types/graphql@types/jestapp-root-dirawesome-typescript-loaderbabel-corebabel-jestbabel-loaderbabel-plugin-lodashbabel-preset-shopifybrowserslistcache-loadercase-sensitive-paths-webpack-pluginchalkcompression-webpack-plugincore-jscss-loaderelement-dataseteslinteslint-plugin-shopifyexpressfile-loaderfs-extraget-portglobgraphqlgraphql-configgraphql-config-utilitiesgraphql-mini-transformsgraphql-typedgraphql-typescript-definitionsgraphql-validate-fixtureshappypackhard-source-webpack-pluginhot-shotsidentity-obj-proxyimage-webpack-loaderis-reachableisomorphic-fetchjestjest-watch-typeaheadjs-yamlloader-utilslodashlodash-webpack-pluginmini-css-extract-pluginnode-object-hashnode-sassopen-in-editoroptimize-css-assets-webpack-pluginpostcss-loaderpostcss-shopifyprettierreact-dev-utilsreact-hot-loaderreact-loadableregenerator-runtimerolluprollup-plugin-babelrollup-plugin-commonjsrollup-plugin-jsonrollup-plugin-node-resolvesass-loadersass-resources-loadersource-map-supportstrip-ansistyle-loaderstylelintstylelint-config-shopifysvgotempterminal-linkterser-webpack-plugintree-killts-loaderurl-loaderwebpackwebpack-bundle-analyzerwebpack-dev-middlewarewebpack-dev-serverwebpack-filter-warnings-pluginwebpack-hot-middlewarewebpack-node-externalswebpack-plugin-hash-outputwhatwg-urlyargs
0.103.3-beta.2

5 years ago

0.103.3-beta.1

5 years ago

1.0.1

5 years ago

1.0.0-beta.12

5 years ago

1.0.0-beta.11

5 years ago

1.0.0-beta.10

5 years ago

1.0.0-beta.9

5 years ago

1.0.0-beta.8

5 years ago

1.0.0-beta.7

5 years ago

1.0.0-beta.6

5 years ago

1.0.0-beta.5

5 years ago

1.0.0-beta.4

5 years ago

1.0.0-beta.3

5 years ago

1.0.0-beta.2

5 years ago

1.0.0-beta.1

5 years ago

1.0.0-beta.0

5 years ago

0.91.0-beta.1

5 years ago

0.91.0-beta.0

5 years ago

0.73.0-beta.2

5 years ago

0.73.0-beta.1

5 years ago

0.68.4-beta.0

5 years ago

0.68.1-beta.1

5 years ago

0.68.0-beta.5

5 years ago

0.68.0-beta.0

5 years ago

0.68.0-beta.4

5 years ago

0.68.0-beta.3

5 years ago

0.68.0-beta.2

5 years ago

0.68.0-beta.1

5 years ago