Last active
October 4, 2016 05:09
-
-
Save kenichi-odo/7435c1eb245ee007aa1aa0626ed56c3c to your computer and use it in GitHub Desktop.
ReactをES2015で書いてVisualforce上で動かす ref: http://qiita.com/kenichi_odo/items/3f19522eaa82eb44115c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cd deploy_salesforce_using_gulp_webpack-2.0 | |
sudo npm i | |
gulp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Force.comのログインユーザ名とパスワードの設定 | |
process.env.SF_USERNAME = 'xxx@xxx.xxx'; | |
process.env.SF_PASSWORD = 'xxxxxxxx'; | |
// moduleのロード | |
import gulp from 'gulp'; | |
import file from 'gulp-file'; | |
import { exec } from 'child_process'; | |
import webpack from 'webpack-stream'; | |
import zip from 'gulp-zip'; | |
import deploy from 'gulp-jsforce-deploy'; | |
import metadata from 'salesforce-metadata-xml-builder'; | |
import os from 'os'; | |
import precss from 'precss'; | |
// ターミナルからgulpを実行した時の処理 | |
gulp.task('default', () => { | |
// original配下のファイルを監視する | |
gulp.watch('./original/**/*').on('change', event => { | |
// Windows or Macのファイル区切り文字 | |
const split_str = os.type().toString().match('Windows') !== null ? '\\' : '/'; | |
// デプロイ時の静的リソース名 | |
// ファイル更新した際の属するフォルダ名(original直下のフォルダ名)を設定 | |
let resource_name = null; | |
// デプロイ時のパス設定 | |
const paths = []; | |
let end_flg = false; | |
for (const path of event.path.split(split_str)) { | |
if (end_flg) { | |
paths.push(path); | |
resource_name = path; | |
break; | |
} | |
if (path === 'original') { | |
end_flg = true; | |
} | |
paths.push(path); | |
} | |
// 静的リソースのメタデータ作成 | |
const resource_meta_xml = metadata.StaticResource({ | |
cacheControl: 'Public', | |
contentType: 'application/zip', | |
}); | |
// デプロイ用package.xmlの作成 | |
const package_xml = metadata.Package({ | |
types: [ | |
{ name: 'StaticResource', members: [resource_name] }, | |
], | |
version: '35.0', | |
}); | |
// ビルドするmain.js | |
const entry = `${paths.join(split_str)}/main.js`; | |
// ビルド開始をMacの通知センターに流す | |
exec(`echo 'display notification "ビルド開始: ${resource_name}" with title "gulp" subtitle "webpack" ' | osascript`); | |
// webpackのビルド | |
gulp.src(entry) | |
.pipe(webpack({ | |
entry, | |
output: { | |
filename: 'bundle.js', | |
libraryTarget: 'umd', // ライブラリとして出力 | |
library: `${resource_name}`, // windowにフォルダ名で書きだして呼び出せるようにする | |
}, | |
devtool: 'inline-source-map', // ビルドしたjsをデバッグできるようにsource mapをインラインで埋め込み | |
module: { | |
loaders: [ | |
{ | |
test: /(\.js)$/, | |
loaders: ['babel'], | |
exclude: /node_modules/, | |
}, | |
{ | |
test: /\.sass$/, | |
loaders: ['style', 'css', 'postcss?parser=sugarss'], | |
}, | |
], | |
}, | |
postcss: [precss], | |
})) | |
.on('error', () => { | |
// webpackのビルドでエラー時、デプロイせずエラーを通知 | |
exec(`echo 'display notification "ビルドエラー: ${resource_name}" with title "gulp" subtitle "webpack" ' | osascript`); | |
}) | |
.pipe(gulp.dest(`./build/${resource_name}`)) // webpackでビルドしたbundle.jsをbuildフォルダに格納 | |
.on('finish', () => { | |
// ビルドの終了を通知 | |
exec(`echo \'display notification "ビルド終了: ${resource_name}" with title "gulp" subtitle "webpack" ' | osascript`); | |
// zip圧縮→デプロイ | |
gulp.src(`./build/${resource_name}/*`) | |
.pipe(zip(`${resource_name}.resource`)) | |
.pipe(file(`${resource_name}.resource-meta.xml`, resource_meta_xml)) | |
.pipe(gulp.dest('./src/staticresources')) | |
.on('finish', () => { | |
// zip圧縮が完了したらデプロイ開始通知 | |
exec( | |
`echo 'display notification "デプロイ開始: ${resource_name}.resource" with title "gulp" subtitle "Salesforce" ' | osascript` | |
); | |
// デプロイ処理 | |
gulp.src('./src/**', { base: '.' }) | |
.pipe(file('src/package.xml', package_xml)) | |
.pipe(zip('pkg.zip')) | |
.pipe(deploy({ | |
username: process.env.SF_USERNAME, | |
password: process.env.SF_PASSWORD, | |
loginUrl: 'https://test.salesforce.com', | |
})) | |
.on('finish', () => { | |
// デプロイが完了したら通知を流す | |
exec( | |
`echo 'display notification "デプロイ完了: ${resource_name}.resource" with title "gulp" subtitle "Salesforce" ' | osascript` | |
); | |
}); | |
}); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import './style/main.sass'; | |
import $ from 'jquery'; | |
import React from 'react'; | |
import ReactDom from 'react-dom'; | |
import SampleComponent from './react/sample-component'; | |
export class Main { | |
constructor(name_) { | |
this._name = name_; | |
this._$sample_component_div = $('<div />'); | |
$('#contents_area').append(this._$sample_component_div); | |
} | |
load() { | |
const items = [{ | |
id: '001', | |
name: 'hoge', | |
}, { | |
id: '002', | |
name: 'fuga', | |
}]; | |
ReactDom.render(<SampleComponent items={ items } />, this._$sample_component_div.get(0)); | |
alert(this._name); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$red: #f00 | |
.hoge-style | |
background: $red |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"devDependencies": { | |
"babel-loader": "^6.2.4", | |
"babel-preset-es2015": "^6.9.0", | |
"babel-preset-react": "^6.5.0", | |
"babel-register": "^6.9.0", | |
… | |
… | |
… | |
}, | |
"babel": { | |
"presets": [ | |
"es2015", | |
"react" | |
], | |
"compact": false | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import Classname from 'classnames'; | |
export default class SampleComponent extends React.Component { | |
constructor(props_) { | |
super(props_); | |
this.state = props_; | |
} | |
componentWillReceiveProps(props_) { | |
this.setState(props_); | |
} | |
render() { | |
if (this.state.items.length === 0) { | |
return null; | |
} | |
return ( | |
<div style={ { display: 'table' } }> | |
{ | |
this.state.items.map(item_ => { | |
return ( | |
<div key={ item_.id } style={ { display: 'table-row' } }> | |
<div className={ Classname({ 'hoge-style': item_.name === 'hoge' }) } style={ { display: 'table-cell' } }> | |
{ item_.name } | |
</div> | |
</div> | |
); | |
}) | |
} | |
</div> | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<apex:page | |
cache="false" | |
sidebar="false" | |
showHeader="false" | |
standardStylesheets="false" | |
applyBodyTag="false" | |
applyHtmlTag="false" | |
docType="html-5.0"> | |
<html> | |
<body> | |
<div id="contents_area"></div> | |
<script src="{!URLFOR($Resource.SampleResource, '/bundle.js')}"></script> | |
<script> | |
var _main = new SampleResource.Main('{!$User.UserName}'); | |
_main.load(); | |
</script> | |
</body> | |
</html> | |
</apex:page> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment