728x90

create-react-app을 사용하여 chrome extension 만들기

React

create-react-app(CRA)는 React 앱을 손쉽게 빌드 및 배포할 수 있는 환경을 제공합니다. 최근 Chrome 확장 프로그램 세팅을 진행하면서 CRA를 사용해 손쉽게 확장 프로그램을 제작하고 싶었지만, CRA는 기본적으로 SPA 만을 지원하여 추가적인 설정이 필요했습니다.

만들려 하는 크롬 익스텐션에서 팝업 환경과 옵션 페이지가 모두 필요하여 빌드 엔트리를 나눌 필요가 있었으나, options_page에 관련된 정보를 찾을 수 없었어서 직접 작업하면서 겪은 과정을 정리합니다.

React App 만들기

우선, create-react-app을 사용하여 React 앱을 만들어 줍니다. 타입스크립트를 사용하기 위해 --template typescript 옵션을 추가하여 생성하겠습니다.

npx create-react-app chrome-extension --template typescript

manifest.json 수정

create-react-app 에서 자동으로 생성해준 manifest.jsonpublic/ 경로에 있지만, chrome extension에서 요구하는 사항에 맞춰 변경해야 합니다.

{
  "name": "Create React App Sample",
  "version": "0.0.1",
  "manifest_version": 2,
  "description": "create-react-app for extensions",
  "icons": {
    "128": "logo128.png"
  },
  "permissions": [],
  "background": {
    "scripts": [
      "background.js"
    ],
    "persistent": true
  },
  "browser_action": {
    "default_icon": "logo128.png",
    "default_popup": "popup.html"
  },
  "options_page": "index.html"
}

option_pageindex.html을 설정하였으며, popuppopup.html로 설정하였습니다.

파일 구조 작업

우선, public 경로에 popup.html을 만들어 준 뒤, src 내에 popup 디렉토리와 page 디렉토리를 각각 생성한 뒤, index.tsx 파일을 만들어줍니다. popup.html의 내용은 index.html을 복사하여 생성하면 됩니다. popuppage 경로에서 공통으로 사용해야 하는 상수, 컴포넌트가 있다면 src 경로 아래 common 디렉토리를 생성합니다. 구조는 다음과 같이 구성됩니다.

또한, src 내에 background.js 파일을 생성한 뒤, chrome extension에서는 인라인 자바스크립트를 허용하지 않으므로 .env 파일을 생성하여 아래 구문을 입력합니다.

INLINE_RUNTIME_CHUNK = false
├─ public
|   ├─ popup.html // popup/index.tsx 가 바라보는 html
|   └─ index.html // page/index.tsx 가 바라보는 html
├─ src
|   ├─ background.js
|   ├─ common // 웹 페이지 및 팝업에서 공용으로 사용되는 로직
|   |   ├─ component // 공용 컴포넌트
|   |   └─ lib // 공용 라이브러리 
|   ├─ page // 크롬 확장 프로그램 웹 페이지
|   |   ├─ index.tsx // 웹 페이지 코드
|   |   ├─ component // 웹 페이지 컴포넌트
|   |   └─ lib // 웹 페이지 라이브러리
|   ├─ popup // 크롬 확장 프로그램 팝업
|   |   ├─ index.tsx // 팝업 코드
|   |   ├─ component // 팝업 컴포넌트
|   |   └─ lib // 팝업 라이브러리
|   |
...

빌드 설정 하기

이제, CRA를 커스터마이징하기 위해 다음 패키지를 추가해줄 필요가 있습니다.

yarn add customize-cra react-app-rewired copy-webpack-plugin react-app-rewire-multiple-entry --dev

customize-crareact-app-rewired는 웹팩을 재정의하며, copy-webpack-plugin을 사용해 public 폴더를 byuld 폴더로 복사할 것입니다. 또한, react-app-rewire-multiple-entry를 이용해 여러 페이지를 빌드할 수 있도록 구성해야 합니다.

루트 경로에 config-overrides.js를 생성한 뒤, 아래와 같이 입력합니다.

const {
  override,
  overrideDevServer,
  addWebpackPlugin
} = require("customize-cra");
const CopyPlugin = require('copy-webpack-plugin');
const RewireMultipleEntry = require('react-app-rewire-multiple-entry');

const multipleEntry = RewireMultipleEntry([
  {
    entry: 'src/popup/index.tsx',
    template: 'public/popup.html',
    outPath: '/popup.html'
  },
  {
    entry: 'src/page/index.tsx',
    template: 'public/index.html',
    outPath: '/index.html'
  }
]);

const devServerConfig = () => config => {
  return {
    ...config,
    writeToDisk: true
  }
}

const copyPlugin = new CopyPlugin({
  patterns: [
    { from: 'public', to: '' },
    { from: 'src/background.js', to: '' }
  ]
})

module.exports = {
  webpack: override(
    addWebpackPlugin(
      copyPlugin
    ),
    multipleEntry.addMultiEntry,
  ),
  devServer: overrideDevServer(
    devServerConfig()
  ),
};

이제 package.json 내의 scripts를 수정하면 커스터마이징한 웹팩 설정을 이용해 빌드할 수 있습니다.

"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test",
  "eject": "react-scripts eject"
},

start, build

yarn run start

명령어를 실행하면 dist 폴더가 생성됩니다. 해당 dist 폴더를 chrome://extensions에 추가하여 개발을 진행할 수 있습니다. 개발이 완료되면 yarn run build 명령어를 실행하여 build 폴더를 생성할 수 있습니다.

모든 것이 정상적으로 완료되었다면 크롬 익스텐션을 클릭하였을 때 아래와 같은 팝업이 노출될 것입니다.

image

728x90
728x90