В данной публикации мы рассмотрим, как создать npm пакет React компонентов используя create-react-app.


Инициализация проекта


create-react-app create-react-app-npm
cd create-react-app-npm
yarn run eject
yarn add -D babel-preset-es2015 babel-preset-stage-0 babel-preset-react

Создать .babelrc


{
  "presets": ["es2015", "react", "stage-0"]
}

Изменить package.json


...
  "name": "create-react-app-npm",
  "version": "0.0.1",
  "main": "lib/index.js",
  "dependencies": {
...
  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "lib": "babel src/node_modules --out-dir lib --copy-files",
    "test": "node scripts/test.js --env=jsdom"
  },
...

Для "приемлемой" загрузки CSS


Изменить config/webpack.config.dev.js


...
      {
        test: /\.css$/,
        loader: `style!css?importLoaders=1&modules&localIdentName=[name]__[local]___[hash:base64:5]!postcss`
      },
...

Изменить config/webpack.config.prod.js


...
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract(
          'style',
          'css?importLoaders=1&modules&localIdentName=[name]__[local]___[hash:base64:5]!postcss',
          extractTextPluginOptions
        )
      },
...

Создать следующую структуру папок:


src/node_modules/
src/node_modules/components/
src/node_modules/components/YourComponent/
src/node_modules/components/YourComponent1/
src/node_modules/components/YourComponent2/
...
src/node_modules/components/YourComponentN/

В каждой папке YourComponent


Создать package.json


{
  "private": true,
  "name": "YourComponent",
  "main": "./YourComponent.js"
}

Создать YourComponent.css (например)


.root {
  background: linear-gradient(to top,#fed835 20px,#ffeb3c 20px);
  font-size: 30px;
  color: white;
  line-height: 35px;
  text-align: center;
}

Создать YourComponent.js


import React                from 'react'

import s                    from './YourComponent.css'

class YourComponent extends React.Component {
  render() {
    return (
      <div className={ s.root }>
        { this.props.children }
      </div>
    )
  }
}

export default YourComponent

Создать src/node_modules/index.js


export { default as YourComponent } from './components/YourComponent'

Для демонстрации работы библиотеки изменить src/App.js


import React                from 'react'

import YourComponent        from 'components/YourComponent'

class App extends React.Component {
  render() {
    return (
      <YourComponent>
        1
      </YourComponent>
    )
  }
}

export default App

Теперь выполнив yarn run start вы можете увидеть, что получилось


Добавьте необходимые пути в .gitignore (например)


/node_modules
/coverage
/build

.DS_Store
.env
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn.lock

.idea

Скомпилируйте библиотеку


yarn run lib

Создайте репозиторий на github


Привяжите проект к созданному репозиторию


git init
git remote add origin https://github.com/lokhmakov/create-react-app-npm.git

Добавьте файлы, сделайте commit и опубликуйте результат


git add .
git commit -m "init"
git push -u origin master
npm publish

Вы закончили. Теперь можно использовать вашу библиотеку следующим образом


yarn add create-react-app-npm

import { YourComponent } from 'create-react-app-npm'

> Create-react-app-npm
Best way to create npm packages with create-react-app

Поделиться с друзьями
-->

Комментарии (13)


  1. ChALkeRx
    10.04.2017 15:37

    "es2015", "react", "stage-0"

    Очень странный набор, ну или информация устаревшая.


    1. Что конкретно из stage-0 вы используете?
    2. На текущий день есть es2016 и es2017.


    1. lokhmakov
      10.04.2017 16:04

      Из «stage-0» не используется ничего, сделано только для включения всего набора stage.

      В боевых условиях: «stage-2», «react».


  1. comerc
    10.04.2017 18:20
    +1

    yarn run eject — в этом месте уже страшно :)


    1. lokhmakov
      10.04.2017 18:26
      +1

      Для слабонервных есть альтернативы! ))

      https://github.com/facebookincubator/create-react-app/issues/682


      1. comerc
        10.04.2017 18:51

        Ага, react-app-rewired уже заюзал для подключения прекрасного пакета Styled JSX:


        Теперь CSS-блоки живут внутри файлов компонентов естественным для себя образом — в CSS-формате (против инлайн-стилей JS-объектов). И не нужно беспокоиться за глобальную область видимости.


        1. lokhmakov
          10.04.2017 18:57

          Мы используем для работы с CSS https://github.com/kriasoft/isomorphic-style-loader

          Который добавляет и убирает CSS в зависимости от того смонтирован компонент или нет (SSR в комплекте), примерно так:

          class YourComponent extends React.Component {
            ...
          }
          
          import withStyles           from 'isomorphic-style-loader/lib/withStyles'
          import s                    from './Root.css'
          
          import { compose }          from 'redux'
          
          export default compose(
            withStyles(s),
          )(YourComponent)
          


        1. lokhmakov
          10.04.2017 18:59

          Так же можно обратить внимание на react-css-themr, который позволяет полностью переопределять стили компонента путем задания другого css.


        1. lokhmakov
          11.04.2017 14:05

          Потестировал Styled JSX и сходу не нашел варианта реализации комплексных селекторов:

          .root {
          }
          
          .root > div {
          }
          


          `root > div` не работает


  1. fr_ant
    11.04.2017 13:58
    +1

    src/node_modules/components/

    а зачем в node_modules то складывать?


    1. lokhmakov
      11.04.2017 14:01
      +1

      После длительной дискуссии `src/node_modules` в `create-react-app` выбрано лучшим решением для абсолютных импортов.

      Для создания библиотеки это так же позволяет решить задачу разделения демонстрационного приложения в стандартной структуре, а самого кода библиотеки в `src/node_modules`.


  1. lokhmakov
    12.04.2017 21:26
    +1

    Вторая статья «Full isomorphic create-react-app + SSR + npm packed shared components with CSS»

    Чуть позже выложу на Хабре.


    1. comerc
      12.04.2017 21:45

      Чем больше сдадим, тем лучше! :)


      1. lokhmakov
        12.04.2017 21:52

        К счастью сдаю сам себе — поэтому все с удовольствием! )