인프런에있는 강좌를 통해 node js를 기반으로 다양한 예제들을 확인했습니다. 진행중인 django 프로젝트에 klaytn플랫폼을 사용해보고싶은데 npm 모듈인 caver-js를 django에서도 사용할 수 있는 방법이있을까요? 답변 부탁드립니다
안녕하세요, Django에서 caver-js를 사용하는 방법은 크게 두가지로 나뉠 것 같습니다.
Webpack
하나는 caver-js를 포함한 Node.js 프로젝트를 webpack으로 번들링하는 방법인데요. 하나의 js 파일로 번들된 결과물을 일반적인 js 라이브러리들 처럼 템플릿에 추가하셔서 사용하면 됩니다. 간단한 예제로 webpack 번들 사용법을 알아보겠습니다.
프로젝트 생성
Node.js 프로젝트 디렉토리로 이동해서 (편의상 $PROJ라고 하겠습니다) npm init으로 Node.js 프로젝트를 생성한 뒤 npm install caver-js로 caver-js를 설치합니다.
~$ cd $PROJ
PROJ$ npm init
PROJ$ npm install caver-js
caver-js는 가급적 최신버전을 사용하시기 바랍니다. 예제는 1.3.2를 사용했습니다.
index.js
다음과 같이 caver-js를 사용하는 index.js 파일을 만듭니다 ($PROJ/index.js 위치에 생성합니다).
const CaverJS = require('caver-js');
const caver = new CaverJS('https://api.baobab.klaytn.net:8651/');
(() => {
caver.klay.getBlockNumber().then((height) => {
console.log(height);
});
})();
console.log('loaded');
webpack.config.js
앞에서 만든 index.js를 번들링하는 webpack 설정파일 webpack.config.js는 다음과 같습니다.
const path = require('path');
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
};
Bundling
index.js와 webpack.config.js가 준비되면 webpack 명령어를 실행하여 $PROJ/dist/bundle.js를 생성합니다. 생성된 bundle.js는 HTML에 <script src="path/to/bundle.js" />로 추가하시면 됩니다. 번들이 추가된 HTML을 불러오면 console에 최신의 블록 번호가 출력되는 것을 확인하실 수 있습니다.
Django Compressor
다른 방법은 Django Compressor를 사용하는 것인데요. compress 태그를 사용하여 npm으로 관리된 ES6 스크립트를 템플릿에 추가할 수 있습니다. 다음 깃허브 링크에서 간단한 예제를 확인하실 수 있습니다: GitHub - w3kim/django-caverjs-example. 이 방법은 compressor와 compressor-toolkit을 사용하여 ES6 스크립트를 하나로 합쳐 넣는 것인데요. 다음과 같이 따라하시면 caver-js를 Django에서 사용하실 수 있습니다.
이 예제는 다음 Gist를 참조하여 작성되었습니다: How to use node.js build routines and npm packages in Django. · GitHub
프로젝트 생성
Django 2.2 기준으로 다음과 같이 프로젝트를 구성해주시면 됩니다.
$ django-admin startproject klaytnexample
$ cd klaytnexample
$ pip install django-compressor django-compressor-toolkit
$ npm init
virtualenv등을 사용하여 프로젝트 Python 환경을 구성하시는 것을 추천합니다.
npm dependencis
package.json을 열어 다음과 같이 디펜던시를 추가해줍니다.
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babelify": "^7.3.0",
"browserify": "^14.4.0",
"node-sass": "^4.5.3",
"postcss-cli": "^4.1.0"
},
"dependencies": {
"caver-js": "^1.3.2"
}
package.json 수정이 완료되면 npm install로 디펜던시들을 설치합니다.
settings.py
klaytnexample/settings.py에 다음과 같이 compress관련 설정을 추가합니다.
# Compressor
INSTALLED_APPS += (
'compressor',
'compressor_toolkit'
)
STATICFILES_FINDERS = [
'compressor.finders.CompressorFinder',
]
COMPRESS_CSS_FILTERS = [
'compressor.filters.css_default.CssAbsoluteFilter',
'compressor.filters.cssmin.CSSMinFilter',
'compressor.filters.template.TemplateFilter'
]
COMPRESS_JS_FILTERS = [
'compressor.filters.jsmin.JSMinFilter',
]
COMPRESS_PRECOMPILERS = (
('module', 'compressor_toolkit.precompilers.ES6Compiler'),
('css', 'compressor_toolkit.precompilers.SCSSCompiler'),
)
COMPRESS_ENABLED = True
COMPRESS_ROOT = os.path.join(BASE_DIR, 'compress')
기존 프로젝트에서
STATICFILES_FINDERS를 사용할 경우STATICFILES_FINDERS에compressor.finders.CompressorFinder를 추가해주시면 됩니다.
test app
Django 프로젝트에 앱을 추가합니다. 앱 이름은 test라고 임의로 설정했습니다.
$ python manage.py startapp test
test/views.py에 다음과 같이 뷰 함수를 추가합니다.
from django.http import HttpResponse
from django.template.loader import render_to_string
def index(request):
rendered = render_to_string('template.html')
return HttpResponse(rendered)
test/urls.py로 적절하게 변경해줍니다.
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
마지막으로 klaytnexample/urls.py에 test 앱의 urls를 추가합니다.
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('test/', include('test.urls')),
path('admin/', admin.site.urls),
]
Template
test 앱이 사용할 템플릿 template.html을 생성합니다. 예제 코드에서 템플릿 위치는 ./home/html로 설정해두었습니다.
<html>
<head>
<title>Django + Node + Caver-js</title>
{% load compress %}
{% compress js %}
<script type="module" src="/static/script.js"></script>
{% endcompress %}
</head>
<body>
<h1>Django + Node + Caver-js</h1>
<h2>Current Block Number: <span id="block-number"></span></h2>
</body>
</html>
ES6 Script
klaytnexample 프로젝트 루트에 compress라는 디렉토리를 만들고 script.js를 작성합니다.
import CaverJS from 'caver-js';
const caver = new CaverJS('https://api.baobab.klaytn.net:8651/');
(() => {
caver.klay.getBlockNumber().then((height) => {
document.getElementById("block-number").innerText = height;
});
})();
실행
python manager.py runserver를 실행한 뒤 localhost:8000/test에 접속하시면 caver-js를 사용하여 최신 블록 번호를 받아 HTML로 값을 표시한 것을 확인할 수 있습니다.
더 궁금하신 것이 있으시면 아래 댓글로 질문 남겨주세요 ![]()
안녕하세요. 현재 서버가 Django 여서 Django를 서비스 이용해보려 하고있습니다.
Django Compressor (두번째 안내 해주신 방법)
type=“module” 하게 되면
‘utf-8’ codec can’t decode byte 0xc0 in position 8: invalid start byte
라는 에러가 나옵니다.
script.js안에 코드가 하나도 없어도 같은 에러가 나옵니다.
즉, type="module"로만 적어도 위 에러가 계속나오는데 구글링해서 해결해보려 하고 있는데
어떻게 방법이 없을까요?ㅠ
안녕하세요, 확인해보니 이 예제를 만들 때 사용된 JS dependencies 조합은 최신버전에서 올바르게 동작하지 않습니다 (약간의 버전 변경이 필요합니다). 우선 급한대로 Django, Django Compressor, Django Compressor Toolkit, caver-js 버전을 최신으로 변경하여 GitHub - w3kim/django-caverjs-example 에 올려두었습니다 (각각 3.2, 2.4.1, 0.6.0, 1.6.1). README를 따라 실행해보시면 script.js에 정의한 대로 caver-js 코드가 동작하는 것을 확인하실 수 있을거에요.
본인의 프로젝트에 Compressor를 적용하실 때 중요한건 compress 디렉토리와 node_modules의 위치, 그리고 사용하는 JS dependencies의 버전들입니다. 최신 버전의 babel이 예전과 동작을 조금 다르게 하는 것 같으니 devDependencies는 아래와 같이 예제에 나온 버전들 그대로 사용하시기 바랍니다.
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babelify": "^7.3.0",
"browserify": "^14.4.0",
"node-sass": "^4.5.3",
"postcss-cli": "^4.1.0"
},