Chrome Extension에 React 적용하기

2021. 8. 18. 15:12프로그래밍/Chrome Extension

오늘도 구글선생님의 힘을 빌려 해보려 한다.

이 블로그의 전체 조회수가 무려 11만회다.

부럽기도 하고 대단하기도 하고 그렇다.

나도 정보글이 아니라 일기 형식으로 찌끄려서 조회수가 안나오나 싶기도 하다.

아무튼 도움이 된 분의 블로그 게시글이다.

https://jungpaeng.tistory.com/79

 

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

create-react-app을 사용하여 chrome extension 만들기 create-react-app(CRA)는 React 앱을 손쉽게 빌드 및 배포할 수 있는 환경을 제공합니다. 최근 Chrome 확장 프로그램 세팅을 진행하면서 CRA를 사용해 손쉽..

jungpaeng.tistory.com


React App 만들기

다음의 명령어로 React 앱을 만든다

npx create-react-app 자기_프로젝트_이름 --template typescript

하나하나 뜯어보자면,

npx는 Node Package Execute의 약자로, 노드 패키지를 실행해주는 명령어이다.
예를 들어, 노드 패키지가 축구 선수들이라고 하면,
NPM은 매니저나 감독이고,
NPX는 전술이나 축구 기술이라고 생각하면 된다.
(비유가 아주 날빌이다)

그래서 이 npx create-react-app을 이용해서 프로젝트를 생성하면,
README.md, Git, node_modules 등과 함께 프로젝트가 세팅이 된다.
예전에는 진짜 프로젝트만 덜렁 만들어줬었던거 같은데 세상 좋아졌다.
-틀-

그리고 마지막으로 --template typescript는,
typescript로 프로젝트를 생성하겠다는 뜻이다.
만약 내가 일반 javascript로 하겠다면, 이 옵션을 빼도 된다.
그리고 앞으로 나오는 .tsx파일은 .jsx파일이라고 생각하면 된다.


manifest.json 수정

public/manifest.json 파일을 수정해주자.

{
  "name": "표시될 이름",
  "version": "0.0.1",
  "manifest_version": 2,
  "description": "이 extension에 대한 설명",
  "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"
}

이 manifest 파일은 chrome extension에서 처리하는 파일이다.
팝업창은 어떤 파일을 읽는지, 어떤 파일이 백그라운드에서 돌아가는지 등에 대한 설정들이다.


파일 구조 작업

글을 읽으면서 느끼는데 파일 정리를 참 깔끔하게 하신다.

우선 루트 경로 (프로젝트 폴더 최상위)에 .env 파일을 생성하고 다음의 내용을 쓴다.

INLINE_RUNTIME_CHUNK = false

CSP과 관련한 에러가 나지 않게 하는 속성이다.

사실 구글은 CSP를 기반으로 인라인 코드를 지양하고 있다. 그래서 죄송하지만 암튼 검사하는 옵션을 끄는거다.
CSP에 대해서는 다음의 글들을 보자.

https://developers.google.com/web/fundamentals/security/csp

 

콘텐츠 보안 정책  |  Web Fundamentals  |  Google Developers

콘텐츠 보안 정책은 최신 브라우저에서 교차 사이트 스크립팅 공격의 위험과 영향을 현저히 줄일 수 있습니다.

developers.google.com

https://ohgyun.com/542

 

크롬 익스텐션의 컨텐트 보안 정책 (CSP)

발생일: 2014.12.28 키워드: Content Security Policy, CSP, Chrome Extension, 크롬 확장, 크롬 익스텐션, angular, google analytics, 구글 애널리틱스 문제: 크롬 익스텐션에서 앵귤러를 사용하려고 추가했는..

ohgyun.com


이제 블로그에 나온대로 파일 정리를 해줬다.


빌드 설정하기

CRA를 커스터마이징 하기 위해서 패키지를 추가해야한다.
다음의 명령어를 실행한다.

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

여기선 CRA란 Create React App이다.
우리가 아까 npx create-react-app했을 때의 그것이다.
아까도 말했듯 react 프로젝트뿐만 아니라 바벨등의 패키기나 git 등도 제공해준다.

CRA를 커스터마이징한다는 것은, 이 CRA의 빌드등의 설정을 바꿔준다는 것이다.

이런 식으로 우리 프로젝트를 관리해주는 매니저 같은 친구다.
이 매니저의 설정을 바꿔주는 것이다.


customize-cra, react-app-rewired

https://www.npmjs.com/package/react-app-rewired

 

react-app-rewired

Tweak the create-react-app webpack config(s) without using 'eject' and without creating a fork of the react-scripts

www.npmjs.com

CRA를 변경하기 위한 패키지들이다.

rewired라는 말에서 알 수 있듯, 새로운 설정으로 갈아끼워서 실행한다는 말이다.


copy-webpack-plugin

https://www.npmjs.com/package/copy-webpack-plugin

 

copy-webpack-plugin

Copy files && directories with webpack

www.npmjs.com

웹팩 번들 시에 파일과 폴더를 목표 지점으로 복사해주는 패키기다.


react-app-rewire-multiple-entry

https://www.npmjs.com/package/react-app-rewire-multiple-entry

 

react-app-rewire-multiple-entry

Multiple Entry Support for Create-React-App

www.npmjs.com

기본적으로 react-app-rewired가 설정되어있어야 하며,

여러 entry를 가질 수 있도록 하는 패키지다.

entry에 대한 설명을 여기서 보자.

https://jeonghwan-kim.github.io/js/2017/05/15/webpack.html

 

웹팩의 기본 개념

자바스크립트 코드가 많아지면 하나의 파일로 관리하는데 한계가 있다. 그렇다고 여러개 파일을 브라우져에서 로딩하는 것은 그만큼 네트웍 비용을 치뤄야하는 단점이 있다. 뿐만 아니라 각 파

jeonghwan-kim.github.io


이제 이 react-app-rewired에서 실행하는 config-overrides.js파일을 생성해보자.

루트 (프로젝트 폴더 최상위)에 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을 수정한다.

"scirpts"항목을 다음처럼 변경한다.


Start, Build

# 빌드하기. /build 폴더 생성
yarn build

# 빌드 + 서버 시작. /dist 폴더 생성
yarn start

원글에는 yarn run start라고 되어있지만 yarn start와 같다.
그리고 빌드만 하더라도 결과물은 같다.


마무리하며

이번에 세팅을 하면서 Webpack, Bable, Loader 등에 대해 조사해봐야겠다고 생각했다.

회사에서 했던 내용들이지만 구현하는데에만 집중하고 원리와 내용에 대한 이해가 없었던 것 같다.