npm 호출시 다음과 같은 에러가 발생했다. 

Error: Cannot find module 'npmlog'
    at Function.Module._resolveFilename (module.js:455:15)
    at Function.Module._load (module.js:403:25)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at /usr/local/lib/node_modules/npm/bin/npm-cli.js:19:13
    at Object.<anonymous> (/usr/local/lib/node_modules/npm/bin/npm-cli.js:75:3)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)

npm 의 문제가 있으니 이를 수정한 업그레이드가 있을까하고 업그레이드를 시도했으니 npm 6.6.0 가 이미 설치되어 있다고 한다. 

✗ brew upgrade npm
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
bacula-fd         erlang            galen             irssi             leiningen         liquibase         macosvpn          open-babel        openssl ✔         openssl@1.1       privoxy           repo              zpaq
 
Error: npm 6.6.0 already installed

그래도 동일한 문제가 발생했다. 이와 관련해서 인터넷 검색을 문제를 찾아보니 Cannot find module 'npmlog' following homebrew update & upgrade가 나왔다.

위에 나온 절차에 따라 node 삭제작업을 진행한다.

brew uninstall node
Uninstalling /usr/local/Cellar/node/6.6.0... (3,669 files, 40.9M)
node 6.1.0, 6.3.1 are still installed.
Remove all versions with `brew uninstall --force node`.
➜  honeymon git:(master) ✗ brew uninstall --force node
Uninstalling node... (7,484 files, 78.5M)
➜  honeymon git:(master) ✗ sudo rm -rf /usr/local/lib/node_modules
Password:
➜  honeymon git:(master) ✗ brew install node
==> Downloading https://homebrew.bintray.com/bottles/node-6.6.0.el_capitan.bottle.tar.gz
Already downloaded: /Users/honeymon/Library/Caches/Homebrew/node-6.6.0.el_capitan.bottle.tar.gz
==> Pouring node-6.6.0.el_capitan.bottle.tar.gz
==> Using the sandbox
==> Caveats
Please note by default only English locale support is provided. If you need
full locale support you should either rebuild with full icu:
  `brew reinstall node --with-full-icu`
or add full icu data at runtime following:
  https://github.com/nodejs/node/wiki/Intl#using-and-customizing-the-small-icu-build
 
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/node/6.6.0: 3,669 files, 40.9M


Gulp

설정 및 설치

  • package.json 생성
{
  "name": "test-front-web",
  "version": "0.0.1.SNAPSHOT",
  "devDependencies": {

  }
}
  • gulp 설치
$ npm install --save-dev gulp 

위의 명령을 실행하고 나면 package.json 파일에 다음과 같이 "gulp": "^3.9.1" 가 추가된 것을 확인할 수 있다.

{
  "name": "test-front-web",
  "version": "0.0.1.SNAPSHOT",
  "devDependencies": {
    "gulp": "^3.9.1"
  }
}

거기에 node_modules 디렉터리가 추가되고 다양한 의존성 라이브러리가 추가되었다.

프로젝트 폴더에 gulpfile.js 를 생성한다. 그리고 그 안에,

// Include gulp
var gulp = require('gulp');

코드를 추가한다.

추가할 수 있는 태스크의 종류는 많지만 그 중에서 몇가지만 소개한다:

  • gulp.task(name, function) - 이름으로 함수를 등록
  • gulp.watch(global, function) - 전역변수의 변경사항이 생겼을 때 호출할 함수 정의
  • gulp.src(global) - 읽어올 위치
  • gulp.dest(folder) - 작성된 파일을 놓을 위치

gulp와 파일 연결하기(Concatenating)

gulp만 설치한다고 끝나는 것은 아니다. gulp 가 동작할 수 있도록 플러그인을 설치하고 gulpfile 에 태스크를 추가해야 한다. gulp-concat 플러그인이 필요하다.

$ npm install --save-dev gulp-concat 

를 실행하고 나면 package.json 에 "gulp-concat": "^2.6.0" 가 추가된다.

이제 gulpfile 에 필요한 테스크를 추가한다.

// Include gulp
var gulp = require('gulp');

// Include plugins
var concat = require('gulp-concat');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function() {
   return gulp.src('src/js/*.js')
       .pipe(concat('honeymon.js'))
       .pipe(gulp.dest('build/js'));
});

// Default Task
gulp.task('default', ['scripts']);

gulp-concat 플러그인 설정을 포함하고 gulp.task 를 사용하여 기본 테스크에 script 를 추가했다. 이 태스크는 3단계 과정으로 처리가 된다:

  1. gulp.src 에서 정의한 src/js 디렉토리에 있는 확장자 js 를 연결한다.
  2. main.js 로 연결한다.
  3. build/js 디렉토리에 main.js 파일을 밀어 넣는다.

gulp 를 이용한 JS 최소화하기

보통 자바스크립트를 배포할 때 최소화(Minify)하는 과정을 거치는데 gulp 에서는 이를 처리하는 플러그인이 있다. 그리고 나서 파일명 접미사로 .min 를 붙이는 rename 플러그인도 함께 설치한다.

$ npm install --save-dev gulp-unglify gulp-renmae 

이제 gulpfile.js 에 scripts 태스크를 수정한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('js'));
});

gulp 를 이용한 css 처리

gulp 를 이용해서 sass 파일을 컴파일하여 css 를 생성하는 태스크를 추가한다.

루비의 공식적인 sass 컴파일러를 설치한다.

$ npm install --save-dev gulp-ruby-sass 

이제 gulpfile.js 에 sass 태스크를 수정한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('build/js'));
});

//Compile SASS
gulp.task('sass', function () {
    sass('src/scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css'));
    sass('src/scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css/honeymon'));
});

// Default Task
gulp.task('default', ['scripts', 'sass']);

프로젝트에 사용하는 이미지 이동

이제 gulp 에서 많은 시간이 걸리는 작업이 남았다. 스크립트나 스타일시트 작업보다 더 오래 걸릴 것이다. gulp-imagemin 와 gulp-cache 를 이용해서 이미지를 최적화하는 작업을 진행한다.

$ npm install --save-dev gulp-imagemin gulp-cache 

gulp-imagemin 와 gulp-cache 에 대한 의존성을 추가하고 image 태스크를 수정하자.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('build/js'));
});

//Move image files
gulp.task('images', function() {
    return gulp.src(srcPath + '/img/**/*')
        .pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass('src/scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css'));
    sass('src/scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css/honeymon'));
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'images', 'sass']);

// Default Task
gulp.task('default', ['build']);

실제로 많이 걸린다..

➜  test-front-web git:(master) ✗ gulp
[14:27:52] Using gulpfile ~/workspace/honeymon/test-front-web/gulpfile.js
[14:27:52] Starting 'scripts'...
[14:27:52] Starting 'images'...
[14:27:52] Starting 'sass'...
[14:27:52] Finished 'sass' after 19 ms
[14:27:52] Finished 'scripts' after 147 ms
[14:27:54] Finished 'images' after 2.18 s
[14:27:54] Starting 'build'...
[14:27:54] Finished 'build' after 1.61 μs
[14:27:54] Starting 'default'...
[14:27:54] Finished 'default' after 1.5 μs

프로젝트에서 작성한 html 을 이동시키자.

html 을 옮기는 과정에서는 2가지 작업을 해야한다.

  • src html 에서 보고 있는 *.css 와 *.js 의 경로를 변경해야 한다.
  • build 로 이동시키면서 빌드 컴파일러된 *.css 와 *.js 를 보도록 변경해야 한다.

우선은 src 에서 build 로 이동처리를 먼저 하자.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');

var buildPath = 'build/'
var srcPath = 'src/'

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src(srcPath + 'js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest(buildPath + 'js'));
});

//Move image files
gulp.task('images', function() {
    gulp.src(srcPath + 'img')
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass(srcPath + 'scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css'));
    sass(srcPath + 'scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css/honeymon'));
});

gulp.task('html-copy', function() {
    gulp.src([srcPath + 'index.html', srcPath + 'sample.html'])
        .pipe(gulp.dest(buildPath))

    gulp.src(srcPath + 'tx/*.html')
        .pipe(gulp.dest(buildPath + '/tx'))
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'images', 'sass', 'html-copy']);

// Default Task
gulp.task('default', ['build']);

이제 gulp-html-replace 플러그인을 설치하고 html 을 옮기면서 stylesheet 와 script 를 처리해보자.

$ npm install --save-dev gulp-html-replace

이제 html-copy 테스크에 추가한다.

gulp.task('html-copy', function () {
    //SEE: https://www.npmjs.com/package/gulp-html-replace
    gulp.src([srcPath + 'sample.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/style.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src([srcPath + 'index.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/index.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src(srcPath + 'tx-*.html')
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/tx.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));
});

src 디렉토리 감시하기

이제 src 디렉토리 내에 있는 파일들의 변경사항이 생겼을 때 이를 감지해서 build 태스크를 실행하도록 만들자.

watch 태스크를 생성한다.

gulp.task('watch', function() {
    // Watch .js files
    gulp.watch(srcPath + 'js/*.js', ['scripts']);
    // Watch .scss files
    gulp.watch(srcPath + 'scss/*.scss', ['sass']);
    // Watch image files
    gulp.watch(srcPath + 'images/**/*', ['images']);
});

그 후 기본 태스크에 watch 태스크를 추가한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');
var htmlReplace = require('gulp-html-replace');
var cleanCSS = require('gulp-clean-css');

var buildPath = 'build/'
var srcPath = 'src/'

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src(srcPath + 'js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest(buildPath + 'js'));
});

//MOVE libraries
gulp.task('libraries', function () {
    //Copy Javascript
    gulp.src([
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/bootstrap/dist/js/bootstrap.min.js',
        'node_modules/bootstrap-select/dist/js/bootstrap-select.min.js'])
        .pipe(gulp.dest(buildPath + 'js/libs'));

    //Copy StyleSheet
    gulp.src([
        'node_modules/bootstrap/dist/css/bootstrap.min.css',
        'node_modules/bootstrap-select/dist/css/bootstrap-select.min.css'])
        .pipe(gulp.dest(buildPath + 'css/libs'));

    //Copy font-awesome
    gulp.src(['./node_modules/font-awesome/css/font-awesome.min.css'])
        .pipe(gulp.dest(buildPath + 'css/libs/font-awesome/css'));
    gulp.src(['./node_modules/font-awesome/fonts/*'])
        .pipe(gulp.dest(buildPath + 'css/libs/font-awesome/fonts'));

    //copy bootstrap
});


//Move image files
gulp.task('images', function () {
    return gulp.src(srcPath + '/img/**/*')
        .pipe(cache(imagemin({optimizationLevel: 5, progressive: true, interlaced: true})))
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass(srcPath + 'scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css'));
    sass(srcPath + 'scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css/honeymon'));
});

//Replace html js, css
gulp.task('html-copy', function () {
    //SEE: https://www.npmjs.com/package/gulp-html-replace
    gulp.src([srcPath + 'sample.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/style.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src([srcPath + 'index.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/index.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src(srcPath + 'tx-*.html')
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/tx.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));
});

//Watch project
gulp.task('watch', function () {
    // Watch .js files
    gulp.watch(srcPath + 'js/*.js', ['scripts']);

    // Watch .scss files
    gulp.watch([srcPath + '**/*.scss'], ['sass']);
    // gulp.watch(srcPath + 'scss/honeymon/*.scss', ['sass']);

    // Watch image files
    gulp.watch(srcPath + 'img/**/*', ['images']);

    // Watch .html files
    gulp.watch(srcPath + '*.html', ['html-copy']);
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'libraries', 'images', 'sass', 'html-copy']);

// Default Task
gulp.task('default', ['build', 'watch']);

이렇게 테스트가 추가되고 나면 src 내에 작은 변화가 생기면 자동적으로 변환이 진행되며 그 결과를 확인할 수 있게 된다.

gulp 동작 실행

gulp 명령어만 실행하면 다음과 같이 build 태스크에 있는 것들이 실행되고 watch 태스크가 실행되면서 디렉토리의 변경사항을 감시하여 변동사항이 생기면 자동으로 빌드가 진행된다.

/usr/local/bin/node /honeymon/node_modules/gulp/bin/gulp.js --color --gulpfile /honeymon//gulpfile.js default
[10:58:15] Using gulpfile ~/workspace/honeymon/test-front-web/gulpfile.js
[10:58:15] Starting 'scripts'...
[10:58:15] Starting 'libraries'...
[10:58:15] Finished 'libraries' after 7.74 ms
[10:58:15] Starting 'images'...
[10:58:15] Starting 'sass'...
[10:58:15] Finished 'sass' after 33 ms
[10:58:15] Starting 'html-copy'...
[10:58:15] Finished 'html-copy' after 14 ms
[10:58:15] Starting 'watch'...
[10:58:15] Finished 'watch' after 56 ms
[10:58:16] Finished 'scripts' after 272 ms
[10:59:31] Starting 'sass'...
[10:59:31] Finished 'sass' after 6.61 ms
[10:59:32] write ./style.css
[11:00:21] Starting 'sass'...
[11:00:21] Finished 'sass' after 5.03 ms
[11:00:22] write ./style.css

참고문헌


'Javascript > Framework & Libs' 카테고리의 다른 글

Error: Cannot find module 'npmlog' 해결  (2) 2016.09.23

+ Recent posts