블로그 이미지
윤영식
Frontend Application Architecter, Full Stacker, KnowHow Dispenser and Bike Rider

Publication

Statistics Graph

Recent Comment

'jhipster'에 해당되는 글 2

  1. 2017.09.06 [JHipster] Clarity를 JHipster에 적용하기
  2. 2017.09.04 [CLI] @angular/cli속의 Webpack 이해하기
2017.09.06 17:55 Angular/Prototyping

Clarity CSS 프레임워크는 VMWare에서 만들어 진 오프소스로써 Twitter Bootstrap 과 같은 업무용 스타일 프레임워크이다. 부트스트랩에 식상한 터라 Clarity의 깔끔함을 JHipster에 적용해 본다. 




Clarity 사용해 보기

clarity가 어떻게 동작하는지 알기 위해 clarity-seed 프로젝트를 다운로드해서 확인해 보자.

$> git clone https://github.com/vmware/clarity-seed.git

$> cd clarity-seed

$> yarn install

$> yarn start

yarn start v0.18.1

$ ng serve

** NG Live Development Server is listening on localhost:4200,


http://localhost:4200 접속 화면




JHipster 설치

JHipster는 Spring Boot + ORM + Angular를 합쳐놓은 Generator이다. JHipster는 과거 yo 기반의 generator-jhipster 를 제공한다.

$> yarn global add yo

$> yarn global add bower

$> yarn global add gulp-cli

$> yarn global add generator-jhipster


generator-jhipster가 설치되었다면 특정위치로 이동해서 jhipster명령을 수행한다. 

- Monolithic으로 선택

- 프로젝트명칭 입력

- JWT 선택

- SQL 선택: MariaDB, development시에는 H2선택

- ehcache 선택

- Maven 선택

- WebSocket 선택

- Angular 4 선택

- libSass 선택

- i18N 선택: ko, en

$> jhipster

Welcome to the JHipster Generator v4.7.0

Documentation for creating an application: https://jhipster.github.io/creating-an-app/

Application files will be generated in folder: /Users/dowonyun/prototyping/jhipster/jamong-admin-seed

? (1/16) Which *type* of application would you like to create? (Use arrow keys)

Monolithic application (recommended for simple projects)

  Microservice application

  Microservice gateway

  [BETA] JHipster UAA server (for microservice OAuth2 authentication)


선택을 완료하면 yarn install이 자동 실행되어 한참을 설치한다. 





Eclipse 설치 및 설정

JHipster 는 Java와 Typescript 코드로 이루어져 있으므로 Eclipse 최신 버전인 Oxygen을 다운로드해 사용한다. JDK8을 기본 사용하므로 사전 설치하고, Eclipse설치가 끝나면 Help메뉴 맨 아래에 있는 Marketplace에서 다음을 설치한다.


- STS (Spring Tool Suite)

- Angular IDE 2017 CI 7

- Dark Theme 설치


테마를 Sublime Text나 Monoaki 를 입히고 싶다면 테마를 검색해서, Eclipse > General > Appearance에서 theme XML 파일을 import 한다. 아래 이미지는 테마를 입힌 후 상태로 "Editor Colors" 밑줄에 "Import a theme..." 이 있다.



설정이 끝났으면 eclipse > file > Import Projects from File System를 통해 생성된 소스를 import 한다.





JHipster 수행

JHipster를 수행하기 위해서는 두개의 명령을 필요로 한다. 서버 수행시 mvnw은 maven이 설치되어 있지 않으면 자동 설치하고 수행하는 명령을 담고 있다. 서버는 8080으로 Listen 을 하고 Angular 클라이언트는 NodeJS기반 Proxy를 통해 8080 포트로 요청을 보낸다.


- 서버 수행: .mvnw

- 클라이언트 수행: yarn start


$> mvnw

... 중략 ...

----------------------------------------------------------

Application 'JamongAdmin' is running! Access URLs:

Local: http://localhost:8080

External: http://218.38.137.28:8080

Profile(s): [swagger, dev]

----------------------------------------------------------


$> yarn start

[Browsersync] Proxying: http://localhost:9060

[Browsersync] Access URLs:

 ---------------------------------------

       Local: http://localhost:9000

    External: http://192.168.202.38:9000

 ---------------------------------------

          UI: http://localhost:3001

 UI External: http://192.168.202.38:3001

 ---------------------------------------


브라우져에서는 9000 로 접속한다. 아래 화면을 이제 Clarity css 프레임워크로 바꿔보자.





Twitter Bootstrap을 Clarity 로 교체하기

Clarity-seed와 JHipster 둘 다 @angular/cli를 기본으로 하고 있기 때문에 루트에 있는 .angular-cli.json에 Clarity 관련 설정을 한다. (설정 사항 참조)


- JHipster는 @ng-bootstrap 모듈을 사용하고, @ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap.js를 사용한다.

- Clarity-seed는 clarity-angular 모듈을 사용한다.


일단, JHispter 프로젝트에서 Clarity관련 Icon 및 UI 설정을 해보자. 


Step 1) 설치

icon은 webcomponent를 사용하기 때문에 웹컴포넌트를 지원하지 않는 브라우져를 위해 polyfill을 설치한다. 

// icon 설치

$> npm install clarity-icons --save

$> npm install @webcomponents/custom-elements@1.0.0 --save


// ui 설치

$> npm install clarity-ui --save

$> npm install clarity-angular --save


Step 2) @angular/cli 설정

JHipster 프로젝트에 별도의 css

"apps": [{

... 중략 ...

       "styles": [

                "../../../node_modules/clarity-icons/clarity-icons.min.css",

                "../../../node_modules/clarity-ui/clarity-ui.min.css",

                "content/scss/vendor.scss",,

                "content/scss/global.scss"

        ],

        "scripts": [

                "../../../node_modules/@webcomponents/custom-elements/custom-elements.min.js",

                "../../../node_modules/clarity-icons/clarity-icons.min.js"

         ],

}]


Step 3) Angular Module 설정

clarity-angular를 사용하기 위해 Angular 모듈에 clarity 모듈을 설정한다. 

// src/main/webapp/app/app.module.ts 안에 

import { ClarityModule } from 'clarity-angular';


@NgModule({

    imports: [

        ...

        // jhipster-needle-angular-add-module JHipster will add new module here

        ClarityModule

    ],

    ...

})



Step 4) yarn start를 하면 @angular/animations 모듈일 없다는 오류가 뜬다. Clarity icon에서 animation 모듈을 사용하기 때문이다.

@angular/animations v4.3.2 버전을 추가한다.

$> npm install @angular/animations@4.3.2 --save






Clarity 컴포넌트 사용하기









<참조>

Clarity 시작하기

- Clarity Icons

신고
posted by peter yun 윤영식
2017.09.04 15:51

Angular 최신 버전이 v5 beta-6를 향해 가고 있다. 9월에는 v5 release가 될 것으로 보인다. Angular에서 툴 기능으로 @angular/cli를 제공하고 있는데 오늘은 이것의 내부구조에 대해 연구해 본다. 



@angular/cli 설치 및 프로젝트 생성

설치는 npm 또는 yarn을 이용한다.

$> npm i -g @angular/cli


or 


$> yarn add global @angular/cli


Angular 기반 프로젝트를 생성해 보자.

$> ng new jamong


실행해 보자

$> ng serve




폴더 구조

angular/cli는 Automation Tool 과 Module loader로 webpack을 사용하고 있다. 웹팩의 환경파일을 루트 폴더에 생성한다. 
$> ng eject
=====================================================
Ejection was successful.

To run your builds, you now need to do the following commands:
   - "npm run build" to build.
   - "npm test" to run unit tests.
   - "npm start" to serve the app using webpack-dev-server.
   - "npm run e2e" to run protractor.

Running the equivalent CLI commands will result in an error.

=====================================================
Some packages were added. Please run "npm install".


설명에 따라 추가 명령을 수행한다. 

$> npm run build && npm start


// package.json의 build 와 start 스크립트 설정내역

  "scripts": {

    "ng": "ng",

    "start": "webpack-dev-server --port=4200",

    "build": "webpack",

    "test": "karma start ./karma.conf.js",

    "lint": "ng lint",

    "e2e": "protractor ./protractor.conf.js",

    "pree2e": "webdriver-manager update --standalone false --gecko false --quiet"

  },



webpack 오류가 난다면 webpack이  global설치가 않되어 있기때문이다. webpack을 설치한다. 

$> yarn add webpack --dev

또는

$> yarn add global webpack 

또는 

$> npm install -g webpack





Webpack 환경파일

webpack의 기본은 초기 참조할 entry파일과 결과 번들파일을 지정하는 것이다. 

$> webpack <entry file path> <output bundle file path>


예) webpack ./entry.js bunlde.js


간단한 번들링은 CLI를 사용해도 무방하지만 복잡한 옵션이 적용되어야 한다면 환경파일을 사용한다. 예) webpack.config.js 아래 예에서 ouput의 filename에 [name]은 entry의 'app' 키값이다. 

module.exports = {

  context: __dirname + '/app',

  entry: {

    app: './app.js'

  },

  output: {

    path: __dirname + '/dist',

    filename: '[name].bundle.js'

  }

}


환경설정 자세한 옵션은 공식문서를 참조한다. 여기서 주의할 것은 entry는 String, Object, Array로 설정가능하다. 

- String: 하나만 설정

- Array: output 번들링 파일에 순서적으로 합쳐진다.

- Object: SPA처럼 index.html에 적용되는 것이 아니라, index1.html 또는 index2.html 등 output이 각각의 html에 포함될 때 사용한다. 





Webpack Loader

Webpack에는 자바스크립트가 아닌 확장형식의 파일을 자바스크립트에서 동작할 수 있도록 해주는 로더(Loader)가 있다. 즉, 모든(CSS, Images, HTML...)을 모듈로 취급하게 해주는 핵심역할을 로더가 수행한다. 말 그대로 다양한 파일 확장자의 Module Loader의 줄임말이라 보면된다. (전체 목록 참조) 만일 설정중에 module, rules를 사용하지않고 loaders를 쓰거나, options대신 query를 쓰면 webpack 1에 대한 설명이다.


- 스타일: style, css

- 변환: typescript, coffeescript, ES2015


환경파일안에 module 밑으로 설정한다. 


module.exports = {

  entry: ...

  output: ...

  module: {

    rules: [

      {

        test: /\.css$/,

        use: [ 'style-loader', 'css-loader']

      }

    ]

    ...

  }


}


특히 Angular 개발시에는 Typescript를 사용하므로 sourcemap을 남기려면 'source-map-loader'를 module 프로퍼티에 설정한다. (sourcemap에 대해 webpack3에서는 plugin으로 설정도 가능하다.) enforce 설정값을 "pre"로 하면 자바스크립트 변환전에 sourcemap 을 만든다.

{

        "enforce": "pre",

        "test": /\.js$/,

        "loader": "source-map-loader",

        "exclude": [

          /(\\|\/)node_modules(\\|\/)/

        ]

}


개발시에는 Node.js기반의 webpack-dev-server를 통해 개발 페이지를 테스트할 수 있다. 옵션은 --inline (전체 페이지 리로딩) --hot (변경 컴포넌트만 리로딩)한다. 

// 전체 및 부분 리로딩 옵션 설정

$> webpack-dev-server --inline --hot




Webpack Plugins

플러그인은 Output 번들의 Chunk 또는 Compilation 레벨 파일에 대한 추가 작업을 수행한다. 예로 ulgifyJSPlugin은 번들 파일 사이즈를 줄이고, 코드를 못 알아보게 만들어 준다. 또는 extract-text-webpack-plugin의 경우는 css-loader, style-loader의 결과를 하나의 별도 외부 파일로 만들어 준다. (플러그인 목록 참조)


@angular/cli에서  ng eject로 나온 webpack.config.js안의 plugins설정 내역

"plugins": [

    new NoEmitOnErrorsPlugin(),

    new GlobCopyWebpackPlugin({

      "patterns": [

        "assets",

        "favicon.ico"

      ],

      "globOptions": {

        "cwd": path.join(process.cwd(), "src"),

        "dot": true,

        "ignore": "**/.gitkeep"

      }

    }),

    new ProgressPlugin(),

    new CircularDependencyPlugin({

      "exclude": /(\\|\/)node_modules(\\|\/)/,

      "failOnError": false

    }),

    new NamedLazyChunksWebpackPlugin(),

    new HtmlWebpackPlugin({

      "template": "./src/index.html",

      "filename": "./index.html",

      "hash": false,

      "inject": true,

      "compile": true,

      "favicon": false,

      "minify": false,

      "cache": true,

      "showErrors": true,

      "chunks": "all",

      "excludeChunks": [],

      "title": "Webpack App",

      "xhtml": true,

      "chunksSortMode": function sort(left, right) {

        let leftIndex = entryPoints.indexOf(left.names[0]);

        let rightindex = entryPoints.indexOf(right.names[0]);

        if (leftIndex > rightindex) {

          return 1;

        } else if (leftIndex < rightindex) {

          return -1;

        } else {

          return 0;

        }

      }

    }),

    new BaseHrefWebpackPlugin({}),

    new CommonsChunkPlugin({

      "name": [

        "inline"

      ],

      "minChunks": null

    }),

    new CommonsChunkPlugin({

      "name": [

        "vendor"

      ],

      "minChunks": (module) => {

        return module.resource &&

          (module.resource.startsWith(nodeModules) ||

            module.resource.startsWith(genDirNodeModules) ||

            module.resource.startsWith(realNodeModules));

      },

      "chunks": [

        "main"

      ]

    }),

    new SourceMapDevToolPlugin({

      "filename": "[file].map[query]",

      "moduleFilenameTemplate": "[resource-path]",

      "fallbackModuleFilenameTemplate": "[resource-path]?[hash]",

      "sourceRoot": "webpack:///"

    }),

    new CommonsChunkPlugin({

      "name": [

        "main"

      ],

      "minChunks": 2,

      "async": "common"

    }),

    new NamedModulesPlugin({}),

    new AotPlugin({

      "mainPath": "main.ts",

      "replaceExport": false,

      "hostReplacementPaths": {

        "environments/environment.ts": "environments/environment.ts"

      },

      "exclude": [],

      "tsConfigPath": "src/tsconfig.app.json",

      "skipCodeGeneration": true

    })

]


JHipster로 자동생된 webpack.config.dev.js의 plugins 설정 내역

plugins: [

        new BrowserSyncPlugin({

            host: 'localhost',

            port: 9000,

            proxy: {

                target: 'http://localhost:9060',

                ws: true

            }

        }, {

            reload: false

        }),

        new webpack.NoEmitOnErrorsPlugin(),

        new webpack.NamedModulesPlugin(),

        new writeFilePlugin(),

        new webpack.WatchIgnorePlugin([

            utils.root('src/test'),

        ]),

        new WebpackNotifierPlugin({

            title: 'JHipster',

            contentImage: path.join(__dirname, 'logo-jhipster.png')

        })

 ]




Production vs Development

개발과 운영 시점에 webpack 환경을 달리 적용하기 위해 보통  webpack.config.dev.js 와 webpack.config.prod.js를  따로 만들고 package.json의 script에 적용해 사용한다. package.json에 적용하고 싶지 않다며 gulp를 사용해도 된다. 


@angular/cli의 script 내역

 "scripts": {

    "ng": "ng",

    "start": "webpack-dev-server --port=4200",

    "build": "webpack",

    "test": "karma start ./karma.conf.js",

    "lint": "ng lint",

    "e2e": "protractor ./protractor.conf.js",

    "pree2e": "webdriver-manager update --standalone false --gecko false --quiet"

}


JHipster script 내역

"scripts": {

    "lint": "tslint --type-check --project './tsconfig.json' -e 'node_modules/**'",

    "lint:fix": "yarn run lint -- --fix",

    "ngc": "ngc -p tsconfig-aot.json",

    "cleanup": "rimraf target/{aot,www}",

    "clean-www": "rimraf target//www/app/{src,target/}",

    "start": "yarn run webpack:dev",

    "serve": "yarn run start",

    "build": "yarn run webpack:prod",

    "test": "karma start src/test/javascript/karma.conf.js",

    "test:watch": "yarn test -- --watch",

    "webpack:dev": "yarn run webpack-dev-server -- --config webpack/webpack.dev.js --progress --inline --hot --profile --port=9060",

    "webpack:build:main": "yarn run webpack -- --config webpack/webpack.dev.js --progress --profile",

    "webpack:build": "yarn run cleanup && yarn run webpack:build:main",

    "webpack:prod:main": "yarn run webpack -- --config webpack/webpack.prod.js --progress --profile",

    "webpack:prod": "yarn run cleanup && yarn run webpack:prod:main && yarn run clean-www",

    "webpack:test": "yarn run test",

    "webpack-dev-server": "node --max_old_space_size=4096 node_modules/webpack-dev-server/bin/webpack-dev-server.js",

    "webpack": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js",

    "e2e": "protractor src/test/javascript/protractor.conf.js",

    "postinstall": "webdriver-manager update && node node_modules/phantomjs-prebuilt/install.js"

}


to be continued...



<참고>

- Webpack core concept

- 네이버 webpack 소개

- Webpack의 혼란스러운 사항들

- Webpack3에서 주의할 점


신고

'' 카테고리의 다른 글

[CLI] @angular/cli속의 Webpack 이해하기  (0) 2017.09.04
posted by peter yun 윤영식
prev 1 next