@shopify/loom-plugin-build-library-extended
TypeScript icon, indicating that this package has built-in type declarations

2.2.0 • Public • Published

@shopify/loom-plugin-build-library-extended

This package is a compliment to @shopify/loom-plugin-build-library. It enhances the build provided by @shopify/loom-plugin-build-library, teaching Rollup and Jest about additional file types. It provides support for parsing styles (.scss files), images (.svg, .jpg, .png files) and graphql (.graphql files). In also provdes type generation for graphql files.

It exposes two plugins - buildLibraryExtended and buildLibraryExtendedWorkspace that should be added to your loom plugins after the buildLibrary and buildLibraryWorkspace plugins provided by @shopify/loom-plugin-build-library.

Installation

$ yarn add @shopify/loom-plugin-build-library-extended --dev

Usage

Add buildLibraryExtended and buildLibraryExtendedWorkspace to your loom plugins.

import {createPackage, Runtime} from '@shopify/loom';
import {
  buildLibrary,
  buildLibraryWorkspace,
} from '@shopify/loom-plugin-build-library';
import {
  buildLibraryExtended,
  buildLibraryExtendedWorkspace,
} from '@shopify/loom-plugin-build-library-extended';

export default createPackage((pkg) => {
  pkg.entry({root: './src/index.js'});
  pkg.use(
    buildLibrary({
      targets: 'defaults, node 12.22',
      commonjs: true,
      esmodules: true,
      esnext: true,
    }),
    buildLibraryWorkspace(),
    buildLibraryExtended({
      // Optional. Defaults to false. Defines if graphql files should be processed.
      graphql: false,
    }),
    buildLibraryExtendedWorkspace({
      // Optional. Defaults to false. Defines if d.ts files should be generated for graphql files.
      graphql: false,
      // Optional. Defaults to `{}`. Defines any overrides for typescript generation, such as exportFormat and customScalars.
      // See https://github.com/Shopify/quilt/blob/main/packages/graphql-typescript-definitions/README.md#node
      generateGraphqlOptions: {},
    }),
  );
});

Styles

.scss files shall be processed using dart-sass, PostCSS and postcss-modules. @shopify/postcss-plugin is used to apply autoprefixing of vendor prefixes and other style transforms.

Create scss files and import them into your JS/TS files. Each style file will expose a default export that is an object containing classnames defined in your style file.

// component.scss
.MyStyle {
  color: red;
}
.MySecondStyle {
  color: blue;
}
// component.tsx
import styles from './component.scss';

export function Component() {
  return (
    <>
      <div className={styles.MyStyle}>I am red</div>
      <div className={styles.MySecondStyle}>I am blue</div>
    </>
  );
}

Currently plain .css files are not supported.

In esmodules builds a styles.css file shall be created at in build/esm/styles.css containing all your scss files concatenated in the order of import. Consuming applications must import this style file. Currently creating a css file per input entrypoint is not supported.

In esnext builds a .css file will be created per .scss file in your source and imports to scss files are placed with imports to the .css file. This allows consumers that understand esnext builds to only include the styles for the components it uses, instead of having to load the styles for all components.

Images

.svg, .png and .jpg expose a default export that is a base64 representation of the image. This value can then be used as the src attribute of img tags. This is good for small images but is an inefficient way of handling larger image. This functionality is provided by @rollup/plugin-image.

// component.tsx
import myImage from './images/my-image.svg';

export function Component() {
  return <img src={myImage} alt="" />;
}

An exception to this is svg files inside an icons folder, which shall expose the svg represented as a React component. This allows the image to be rendered as a React component, or passed into @shopify/polaris's Icon component. This functionality is provided by @svgr/rollup.

// component.tsx
import {Icon} from '@shopify/polaris';
import MyIcon from './icons/my-icon.svg';

export function Component() {
  return (
    <>
      <MyIcon />
      <Icon source={MyIcon} />
    </>
  );
}

GraphQL

.graphql files expose a default export that is the query provided by the file. This functionality is provided by @rollup/plugin-graphql.

# bookList.graphql
query BookList {
  books {
    id
    title
    genre
  }
}
// component.tsx
import {useQuery} from '@shopify/react-graphql';
import bookList from './myQuery.graphql';

export function Component() {
  const {data, error, loading} = useQuery(bookList);
  return JSON.stringify({data, error, loading});
}

When you call buildLibraryExtendedWorkspace({graphql: true}) .d.ts files shall be generated for all graphql files as part of your pre-build and type-check steps using graphql-typescript-definitions. This exposes type exports of GraphQL data shapes. For instance in the above example bookList.graphqlshall expose a BookListQuery interface. This requires the presense of a .graphqlconfig file that references your schema. See graphql-typescript-definitions's readme for more information on how to configure this.

Generate graphql types that enable type inferrence with Apollo 3's hooks

By default graphql-typescript-definitions generates types that enable type inferrence in the hooks provided by @shopify/react-graphql and other quilt-based packages. If you want to use Apollo 3's hooks instead, you must adjust the exportFormat option.

If you need types that work with both @graphql-typed-document-node/core (used by Apollo 3) and graphql-typed (used by @shopify/react-graphql and other quilt-based packages) use ExportFormat.DocumentWithTypedDocumentNode. You only need Apollo 3 support use ExportFormat.TypedDocumentNode. You must be using at least graphql-typescript-definitions v3.3.0 to use these value.

import {createPackage, Runtime} from '@shopify/loom';
import {
  buildLibrary,
  buildLibraryWorkspace,
} from '@shopify/loom-plugin-build-library';
import {
  buildLibraryExtended,
  buildLibraryExtendedWorkspace,
} from '@shopify/loom-plugin-build-library-extended';
import {ExportFormat} from 'graphql-typescript-definitions';

export default createPackage((pkg) => {
  pkg.entry({root: './src/index.js'});
  pkg.use(
    buildLibrary({
      targets: 'defaults, node 12.22',
      commonjs: true,
      esmodules: true,
      esnext: true,
    }),
    buildLibraryWorkspace(),
    buildLibraryExtended({graphql: true}),
    buildLibraryExtendedWorkspace({
      graphql: true,
      generateGraphqlOptions: {
        exportFormat: ExportFormat.DocumentWithTypedDocumentNode,
      },
    }),
  );
});

Overriding PostCSS config

We provide an initial PostCSS config that supports autoprefixing, using @shopify/postcss-plugin. If you need to adjust this config, you can call the postcss() plugin after buildLibraryExtended to override the defaults.

import {createPackage} from '@shopify/loom';
import {
  buildLibrary,
  buildLibraryWorkspace,
} from '@shopify/loom-plugin-build-library';
import {
  buildLibraryExtended,
  buildLibraryExtendedWorkspace,
  postcss,
} from '@shopify/loom-plugin-build-library-extended';
import {myPostcssPlugin} from 'my-postcss-plugin';

export default createPackage((pkg) => {
  pkg.entry({root: './src/index.js'});
  pkg.use(
    buildLibrary({targets: 'node 12.22.0', commonjs: true}),
    buildLibraryWorkspace(),
    buildLibraryExtended(),
    buildLibraryExtendedWorkspace(),
    // Override initial postcss options.
    // Return a new object, instead of mutating the argument object.
    postcss({
      config(postcssConfig) {
        return {
          ...postcssConfig,
          plugins: [...(postcssConfig.plugins || []), myPostcssPlugin()],
        };
      },
    }),
  );
});

Readme

Keywords

none

Package Sidebar

Install

npm i @shopify/loom-plugin-build-library-extended

Weekly Downloads

356

Version

2.2.0

License

MIT

Unpacked Size

35.1 kB

Total Files

29

Last publish

Collaborators

  • jaimie.rockburn
  • blittle
  • shopify-admin
  • maryharte
  • crisfmb
  • pmoloney89
  • netlohan
  • st999999
  • justin-irl
  • megswim
  • wcandillon
  • nathanpjf
  • shopify-dep
  • goodforonefare
  • lemonmade
  • vsumner
  • wizardlyhel
  • antoine.grant
  • tsov
  • andyw8-shopify
  • henrytao
  • hannachen
  • vividviolet
  • bpscott