react 동 질감 에 대한 간단 한 설명

13886 단어 react.동구
머리말
이 글 은 같은 구성 서버 를 통 해 html 구 조 를 렌 더 링 할 수 있다 고 설명 했다.스타일,이미지 등 정적 자원 이 서버 에 문 제 를 도입 하 는 해결 방안 을 설 명 했 지만 실제 적 으로 관련 작업 을 하지 않 았 다.이 글 은 html 처럼 스타일 을 직 설 적 으로 만 드 는 방법 을 설명 했다.
PS:직 출,내 이 해 는 url 을 입력 하여 get 요청 서버 에 접근 하 는 것 입 니 다.ajax 비동기 가 아 닌 전체 응답 결 과 를 얻 는 것 입 니 다.
React 동구 의 관건 요소
완벽 한 Compponent 속성 과 생명주기 와 클 라 이언 트 의 render 시 기 는 React 동구 의 관건 이다.
DOM 의 일치 성
같은 Compponent 를 앞 뒤로 렌 더 링 하여 같은 Dom 구 조 를 출력 합 니 다.
다른 생명주기
서버 에서 Component 수명 주 기 는 component WillMount 에 만 있 고 클 라 이언 트 는 완전 합 니 다.
클 라 이언 트 render 타 이 밍
같은 구성 일 때 서버 에서 데 이 터 를 결합 하여 Component 를 완전한 HTML 문자열 로 렌 더 링 하고 데이터 상 태 를 클 라 이언 트 에 게 되 돌려 줍 니 다.클 라 이언 트 는 직접 사용 하거나 다시 마 운 트 해 야 하 는 지 판단 합 니 다.
이상 은 React 가 같은 구성/서버 에서 렌 더 링 하 는 기본 조건 입 니 다.실제 프로젝트 응용 에 서 는 서버 쪽 에 window 대상 이 없고 서로 다른 처리 가 필요 하 다 는 등 다른 변 각 문 제 를 고려 해 야 한다.다음은 손 Q 개 학교 군 에서 의 구체 적 인 실천 을 통 해 같은 구조의 Tips 와 최적화 성 과 를 공유 하 겠 습 니 다.
스타일 파일 추가
현재 프로젝트 에 스타일 파일 이 존재 하지 않 기 때문에 먼저 작성 해 야 합 니 다.구성 요소 App 에 스타일 파일 을 쓰 십시오.
설치 의존
아래 의 이러한 의존 은 모두 후속 적 으로 사용 할 것 이다.먼저 설치 하고 다음은 모든 의존 작용 을 상세 하 게 설명 할 것 이다.

npm install postcss-loader postcss-import postcss-cssnext postcss-nested postcss-functions css-loader style-loader isomorphic-style-loader --save-dev
.pcss 파일 만 들 기
css 파일 의 접 두 사 는.css 입 니 다.less 파일 의 접 두 사 는.less 입 니 다.여기 서 저 는 PostCSS 를 사용 하여 플러그 인 에 맞 춰 스타일 을 쓰 는 것 을 선 택 했 습 니 다.그래서 접 두 사 를.pcss 로 정의 하 겠 습 니 다.

// ./src/client/component/app/style.pcss

.root {
 color: red;
}

루트 클래스 를 설정 합 니 다.스타일 은 빨간색 으로 간단하게 설정 합 니 다.그리고 App 구성 요소 에서 참조 합 니 다.

// ./src/client/component/app/index.tsx

...
import * as styles from './style.pcss';
...
 public render() {
  return (
   <div className={styles.root}>hello world</div>
  );
 }
...

이 럴 때 편집기 에 이렇게 있 는 것 을 발견 할 수 있 습 니 다.

이 문 제 는 ts 가 이 모듈 의 유형 정 의 를 모 르 기 때문에 사용자 정의 모듈 형식 정 의 를 수 동 으로 추가 해 야 합 니 다.프로젝트 루트 디 렉 터 리 에@types 폴 더 를 새로 만 듭 니 다.이 디 렉 터 리 에 index.d.ts 파일 을 만 듭 니 다.

// ./@types/index.d.ts

declare module '*.pcss' {
 const content: any;
 export = content;
}
저장 하면 편집기 가 잘못 보고 되 는 것 을 보지 않 습 니 다.하지만 terminal 에 서 는 webpack 패키지 에 오류 가 발생 할 수 있 습 니 다.아직 loader 를 추가 하지 않 았 기 때 문 입 니 다.
.pcss 파일 의 해석 규칙 설정
js 가 구성 요소 화 되 었 으 니 css 모듈 화 도 필요 합 니 다.중복 되 는 이름 을 피하 기 위해 고민 하지 않 아 도 됩 니 다.우 리 는 base 설정 에서 postcss 의 규칙 을 얻 기 위해 새로운 방법 을 내 보 냅 니 다.

// ./src/webpack/base.ts

...
export const getPostCssRule = (styleLoader) => ({
 test: /\.pcss$/,
 use: [
  styleLoader,
  {
   loader: 'css-loader',
   options: {
    camelCase: true,
    importLoaders: 1,
    localIdentName: '[path][name]---[local]---[hash:base64:5]',
    modules: true,
   },
  },
  {
   loader: 'postcss-loader',
   options: {
    plugins: () => [
     require('postcss-import')({
      path: path.join(baseDir, './src/client/style'),
     }),
     require('postcss-cssnext'),
     require('postcss-nested'),
     require('postcss-functions')({
      functions: {
       x2(v, u) {
        return v * 2 + (u ? u : 'px');
       },
      },
     }),
    ],
   },
  },
 ],
});
...

우 리 는 위 에서 이 방법 을 볼 수 있 습 니 다..pcss 파일 을 처리 하려 면 세 개의 loader 를 사용 해 야 합 니 다.처리 순서에 따라 아래 에서 위로 각각 postcss-loader,css-loader,그리고 하나의 변수 styleLoader 가 있 습 니 다.이 변수 가 무엇 인지 우 리 는 이 방법 을 사용 하 는 곳 을 볼 수 있 습 니 다.

// ./src/webpack/client.ts

...
(clientDevConfig.module as webpack.NewModule).rules.push(
 ...
 getPostCssRule({
  loader: 'style-loader',
 }),
 ...
);
...


// ./src/webpack/server.ts

...
(clientDevConfig.module as webpack.NewModule).rules.push(
 ...
 getPostCssRule({
  loader: 'isomorphic-style-loader',
 }),
 ...
);
...

클 라 이언 트 와 서버 에서 스타일 파일 을 처리 하려 면 서로 다른 styleLoader 를 사용 해 야 합 니 다.
PostCSS 소개
PostCSS 는 js 를 사용 하여 css 를 변환 하 는 도구 입 니 다.이것 은 공식 소개 입 니 다.웹 팩 에 맞 춰 사용 하 는 loader 는 postcss-loader 이지 만 하나의 postcss-loader 만 으로 는 소 용이 없 으 며 플러그 인 에 맞 춰 강력 한 기능 을 수행 해 야 합 니 다.
1、postcss-import
이 플러그 인 은 스타일 파일 에서@import 를 사용 할 때 복잡 한 경 로 를 피하 기 위해 서 입 니 다.path 값 을 설정 하면 다른 모든 단계 의 스타일 파일 에 path 대응 폴 더 의 공공 변수 스타일 파일("variables.pcss"라 고 가정 할 때 매우 편리 합 니 다.import'variables.pcss'만 쓰 면 됩 니 다.됐 습 니 다.물론 해당 하 는 파일 을 찾 지 못 하면 path 를 무시 하고 기본 상대 경 로 를 사용 하여 찾 습 니 다.
2、postcss-cssnext
이 플러그 인 은 차세 대 css 문법 을 사용 할 수 있 습 니 다.
3、postcss-nested
이 플러그 인 은 스타일 을 끼 워 넣 을 수 있 습 니 다.
4、postcss-functions
이 플러그 인 은 함 수 를 사용자 정의 하고 스타일 파일 에서 호출 할 수 있 습 니 다.
이렇게 많아
저 희 는 client 디 렉 터 리 에 style 폴 더 를 추가 하여 스타일 reset,변수 파일 같은 것 을 저장 합 니 다.그리고 pcss 파일 두 개 만 들 기:

// ./src/client/style/variables.pcss

:root {
 --fontSizeValue: 16;
}

// ./src/client/style/index.pcss

@import 'variables.pcss';

body {
 margin: 0;
 font-size: x2(var(--fontSizeValue));
}

우리 가 방금 쓴 index.pcss 를 도입 합 니 다.

// ./src/client/index.tsx
...
import './style/index.pcss';
...
CSS 모듈 개요
쉽게 말 하면 css 모듈 화 입 니 다.전체 클래스 의 문 제 를 걱정 하지 않 아 도 됩 니 다.우 리 는 상술 한 css-loader 의 options 에 근거 하여 볼 때:
  • camelCase 는 true 운행 을 위해 낙타 봉 표기 법 으로 유형 명 을 쓴다
  • importLoaders 의 값 이 N 인 것 은 css-loader 이전에 N 개의 loader 가 파일 을 처 리 했 기 때 문 입 니 다.여기 N 값 은 1 입 니 다.이전에 postcss-loader 가 있 었 기 때 문 입 니 다.이 값 은 반드시 설정 해 야 합 니 다.그렇지 않 으 면@import 구문 에 영향 을 줄 수 있 습 니 다.제 표현 이 정확 하지 않 을 수도 있 습 니 다.상세 한 것 은 참조 할 수 있 습 니 다Clarify importLoaders documentation?대충 번역 해 보 겠 습 니 다.이 속성의 값 N 은@import 파일 에 대해 css-loader 뒤의 N 개의 loader 처 리 를 거 쳐 야 한 다 는 것 을 의미 합 니 다.영어 가 잘 되 지 않 으 니 스스로 이해 하 셔 도 됩 니 다
  • local IdentName 이란 생 성 된 클래스 이름 을 말 합 니 다.구체 적 으로 후속 결 과 를 보면 캡 처 를 한눈 에 알 수 있 습 니 다
  • modules 는 true 즉 모듈 화 를 사용 합 니 다isomorphic-style-loader
    클 라 이언 트 에 서 는 style-loader 를 사용 합 니 다.dom 에 style 요 소 를 동적 으로 삽입 합 니 다.서버 는 클 라 이언 트 의 관련 대상 과 API 가 부족 하기 때문에 isomorphic-style-loader 가 필요 합 니 다.현재 사용 하 는 것 은 오류 가 발생 하지 않도록 하 는 것 입 니 다.후속 적 으로 큰 역할 을 합 니 다.스타일 은 모두 그것 에 의존 합 니 다.
    포장 운행
    메모:패키지 가 실행 되 기 전에 tsconfig.client.json 과 tsconfig.server.json 에 사용자 정의 모듈 정의 파일 index.d.ts 를 도입 하 는 것 을 잊 지 마 세 요.그렇지 않 으 면 웹 팩 컴 파일 은 pcss 라 는 모듈 을 찾 을 수 없습니다.
    
    // ./src/webpack/tsconfig.client(server).json
    ...
    "include": [
      ...
      "../../@types/**/*",
      ...
    ]
    ...
    
    실행 결 과 는 다음 과 같 습 니 다.

    style 요 소 는 이미 존재 하지만 이것 은 style-loader 에서 생 성 된 것 입 니 다.서버 에서 직접 나 온 것 이 아 닙 니 다.page source 를 보면 알 수 있 습 니 다.

    또한 페이지 를 새로 고 칠 때 스타일 변화 가 반 짝 이 는 효 과 를 뚜렷하게 볼 수 있다.
    직 출 양식
    저 희 는 isomorphic-style-loader 를 이용 하여 서버 의 직 출 스타일 을 실현 합 니 다.원 리 는 공식 소개 에 따 르 면 react 의 context api 를 이용 하여 이 루어 집 니 다.서버 가 렌 더 링 하 는 과정 에서 주입 한 insertCss 방법 과 고급 구성 요소(hoc-high-order component)를 이용 하여 스타일 코드 를 가 져 옵 니 다.
    설치 의존
    
    npm install prop-types --save-dev
    App 구성 요소 바 꾸 기
    공식 소개 에 따 르 면,우 리 는 통 합 된 isomorphic router 를 사용 하지 않 은 상태 에서 Provider 를 App 구성 요소 에 써 야 합 니 다.
    
    // ./src/client/component/app/provider.tsx
    
    import * as React from 'react';
    
    import * as PropTypes from 'prop-types';
    
    class AppProvider extends React.PureComponent<any, any> {
     public static propTypes = {
      context: PropTypes.object,
     };
    
     public static defaultProps = {
      context: {
       insertCss: () => '',
      },
     };
    
     public static childContextTypes = {
      insertCss: PropTypes.func.isRequired,
     };
    
     public getChildContext() {
      return this.props.context;
     }
    
     public render() {
      return this.props.children || null;
     }
    }
    
    export default AppProvider;
    
    
    원래 App 구성 요소 의 구체 적 인 내용 을 AppContent 구성 요소 로 옮 깁 니 다.
    
    // ./src/client/component/app/content.tsx
    
    import * as React from 'react';
    
    import * as styles from './style.pcss';
    
    /* tslint:disable-next-line no-submodule-imports */
    import withStyles from 'isomorphic-style-loader/lib/withStyles';
    
    @withStyles(styles)
    class AppContent extends React.PureComponent {
     public render() {
      return (
       <div className={styles.root}>hello world</div>
      );
     }
    }
    
    export default AppContent;
    
    
    새로운 App 구성 요소:
    
    // ./src/client/component/app/index.tsx
    
    import * as React from 'react';
    
    import AppProvider from './provider';
    
    import AppContent from './content';
    
    class App extends React.PureComponent {
     public render() {
      return (
       <AppProvider>
        <AppContent />
       </AppProvider>
      );
     }
    }
    
    export default App;
    
    
    의문 1:AppProvider 구성 요 소 는 무엇 을 합 니까?
    답:Provider 는 공급 자,공급 자 라 는 뜻 입 니 다.말 그대로 AppProvider 는 후대 구성 요소 에 뭔 가 를 제공 했다.이것 이 바로 context 이 고 insertCss 방법 이 있다.그 정의 에 따 르 면 이 방법 은 기본 값 을 가지 고 있 으 며 빈 문자열 을 되 돌려 주 는 함수 입 니 다.즉,기본 값 은 아무 소 용이 없 지만 props 를 통 해 context 에 들 어가 사용자 정의 목적 을 달성 할 수 있 습 니 다.childContextTypes 와 getChildContext 를 설정 하면 이 구성 요소 의 후손 은 contextTypes 를 설정 한 구성 요소 라면 this.context 대상 을 가지 고 있 으 며,이 대상 은 getChildContext 의 반환 값 입 니 다.
    의문 2:AppContent 는 왜 독립 해 야 합 니까?
    답:다음 질문 을 받 았 습 니 다.AppProvider 구성 요소 render 의 하위 구성 요소 입 니 다.context 라 는 api 를 적용 하려 면 하위 구성 요 소 는 contextTypes 를 정의 해 야 합 니 다.그러나 우 리 는 AppContent 에 이러한 정의 가 있 는 것 을 보지 못 했 습 니 다.이것 은 이 정의 가 고급 구성 요소 with Styles 에 있 기 때 문 입 니 다(4.567915 참조).
    질문 3:@with Styles 는 무슨 문법 입 니까?
    답:이것 은 장식 기 입 니 다.es7 에 속 합 니 다.이 문법 을 사용 하려 면 tsconfig 를 설정 해 야 합 니 다.
    
    // ./tsconfig.json
    // ./src/webpack/tsconfig.client(server).json
    
    {
     ...
     "compilerOptions": {
      ...
      "experimentalDecorators": true,
      ...
     },
     ...
    }
    
    
    서버 bundle 파일 바 꾸 기
    앱 구성 요소 의 변경 으로 서버 에서 이 구성 요 소 를 다시 사용 할 수 없 지만,앱 프로 바 이 더 와 앱 콘 텐 츠 는 아직 다시 사용 할 수 있 습 니 다.
    
    // ./src/server/bundle.tsx
    
    import * as React from 'react';
    
    /* tslint:disable-next-line no-submodule-imports */
    import { renderToString } from 'react-dom/server';
    
    import AppProvider from '../client/component/app/provider';
    
    import AppContent from '../client/component/app/content';
    
    export default {
     render() {
      const css = [];
      const context = { insertCss: (...styles) => styles.forEach((s) => css.push(s._getCss())) };
      const html = renderToString(
       <AppProvider context={context}>
        <AppContent />
       </AppProvider>,
      );
      const style = css.join('');
      return {
       html,
       style,
      };
     },
    };
    
    
    css 라 는 변 수 를 통 해 style 정 보 를 저장 할 수 있 는 사용자 정의 context 대상 이 들 어 왔 습 니 다.우 리 는 원래 render 함수 가 renderToString 의 html 문자열 을 직접 되 돌려 주 었 는데,지금 은 style 이 하나 더 생 겼 기 때문에 html 와 style 속성 을 가 진 대상 을 되 돌려 줍 니 다.
    의문 4:공식 예제 css 는 set 형식 인 스 턴 스 입 니 다.여 기 는 어떻게 배열 형식 인 스 턴 스 입 니까?
    답:set 는 es6 의 새로운 데이터 구조 로 배열 과 유사 하지만 중복 값 이 없 음 을 보증 할 수 있 습 니 다.tsconfig 의 컴 파일 옵션 중의 target 이 es6 일 때 만 es2017 lib 에 가입 할 때 오류 가 발생 하지 않 습 니 다.우리 의 target 은 es5 이기 때문에 배열 이 고 배열 을 사용 하 는 데 큰 문제 가 없습니다.
    서버 입구 파일 처리
    bundle 의 render 값 이 변경 되 었 기 때문에 우리 도 처리 해 야 합 니 다.
    
    // ./src/server/index.tsx
    
    ...
    router.get('/*', (ctx: Koa.Context, next) => { //        get    
     const renderResult = bundle ? bundle.render() : {}; //           
     const { html = '', style = '' } = renderResult;
     ...
     ctx.body = `
      ...
      <head>
       ...
       ${style ? `<style>${style}</style>` : ''}
       ...
      </head>
      ...
     `;
     ...
    });
    ...
    
    
    결 과 를 내다
    스타일 이 나 온 후 page source:

    잃 어 버 린 공공 스타일 파일 찾기
    위의 직 출 결 과 를 보면.../src/style/index.pcss 라 는 스타일 코드 가 부족 합 니 다.이 유 는 분명 합 니 다.구성 요소 에 속 하지 않 고 공공 입 니 다.클 라 이언 트 입구 파일 에 도입 되 었 습 니 다.공공 스타일 파일 에 대해 서 는 서버 에서 이 부분 을 똑바로 해 야 합 니 다.이렇게 할 수 있 습 니 다.
    
    ./src/server/bundle.tsx
    
    ...
    import * as commonStyles from '../client/style/index.pcss';
    ...
    const css = [commonStyles._getCss()];
    ...
    
    
    저 희 는 isomorphic-style-loader 가 제공 하 는 api 를 이용 하여 이 부분 스타일 코드 문자열 을 얻 을 수 있 습 니 다.이렇게 하면 완전한 직 출 스타일 을 얻 을 수 있다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기