webpack 使えば比較的簡単
ソースは以下
https://github.com/ninomae-makoto/share-code-between-server-and-client
環境
Visual Studio Code
Node.js (6〜)
Webpack 4
TypeScript 2.7
ディレクトリ構成
public/ javascripts/ /dist webpack出力先 f_index.ts routes/ b_index.ts common/ common.ts
common.tsに共通処理を書いてf_index.ts(ブラウザ),b_index.ts(サーバ)から呼び出す。
プログラムソース
common.ts
1 2 3 4 5 6 | export class Common { public static test() { console.log( "test" ) } } |
index.pug
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | doctype html html head meta(http-equiv= "X-UA-Compatible" , content= "IE=edge" ) meta(charset= 'UTF-8' ) meta( name= "viewport" , content= "width=device-width, initial-scale=1" ) meta( name= "robots" content= "noindex, nofollow" ) title= title link(rel= 'stylesheet' , href= '/stylesheets/style.css' ) //- link(rel="icon" type="image/png" href="/images/favicon.png") body script(src= "./javascripts/dist/index.built.js" ) h1 サーバ・クライアント共通化 |
サーバ側の処理
b_index.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 | import * as express from "express" import { Common } from "./../common/common" { const router = express.Router() /* GET home page. */ router.get( "/" , ({ }, res, { }) => { Common.test() res.render( "index" ) }) module.exports = router } |
フロント側の処理
f_index.ts
1 2 3 | import { Common } from "./../../common/common" Common.test() |
サーバ・フロントそれぞれでCommon.test()を呼び出している。
Webpack設定ファイル
webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | var path = require( 'path' ) var webpack = require( 'webpack' ) var HardSourceWebpackPlugin = require( 'hard-source-webpack-plugin' ) module.exports = { entry: { index: './public/javascripts/f_index.ts' , }, output: { path: path.resolve(__dirname, './public/javascripts/dist' ), publicPath: '/dist/' , filename: '[name].built.js' }, module: { rules: [ { test: /\.js$/, include: path.resolve( "src" ), use: [ { loader: "thread-loader" , options: { workers: require( 'os' ).cpus().length - 1, } } // your expensive loader (e.g babel-loader) ] }, { enforce: 'pre' , test: /\.ts$/, loader: 'tslint-loader' , exclude: /(node_modules)/, options: { configFile: 'tslint.json' } }, { test: /\.ts$/, exclude: /node_modules|vue\/src/, loader: 'ts-loader' , options: { appendTsSuffixTo: [/\.vue$/], transpileOnly: true } }, { test: /\.vue$/, loader: 'vue-loader' , options: { loaders: { // Since sass-loader (weirdly) has SCSS as its default parse mode, we map // the "scss" and "sass" values for the lang attribute to the right configs here. // other preprocessors should work out of the box, no loader config like this necessary. // 'scss': 'vue-style-loader!css-loader!sass-loader', // 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax', 'ts' : 'ts-loader!tslint-loader' , } // other vue-loader options go here } } ] }, resolve: { extensions: [ '.ts' , '.js' , '.vue' , '.json' ], alias: { 'vue$' : 'vue/dist/vue.esm.js' } }, devServer: { historyApiFallback: true , noInfo: true }, externals: { "vue" : "Vue" }, cache: true , performance: { hints: false }, devtool: '#eval-source-map' } module.exports.plugins = (module.exports.plugins || []).concat([ new HardSourceWebpackPlugin(), ]) |
気にするところはentryとoutputくらい
詳細は以下
https://trueman-developer.blogspot.jp/2018/02/typescript.html
https://trueman-developer.blogspot.jp/2018/03/webpack3webpack4.html
tsconfig.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | { "compilerOptions" : { "outDir" : "./built/" , "sourceMap" : true , "strict" : true , "noImplicitReturns" : true , "module" : "es2015" , "moduleResolution" : "node" , "target" : "es5" }, "include" : [ "./public/javascripts/*" , "./public/javascripts/**/*" ], "exclude" : [] } |
クライアントのトランスパイル用
webpackから呼ばれる
tsconfig_node.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | { "compilerOptions" : { "allowSyntheticDefaultImports" : true , "target" : "ES5" , "module" : "commonjs" , "sourceMap" : true , "declaration" : true , "inlineSources" : true , "moduleResolution" : "node" , "rootDir" : "." , "noImplicitAny" : true , "strictNullChecks" : true , "noImplicitThis" : true , "alwaysStrict" : true , "noUnusedLocals" : true , "noUnusedParameters" : true , "noImplicitReturns" : true , "noFallthroughCasesInSwitch" : true , "forceConsistentCasingInFileNames" : true , "newLine" : "LF" , "lib" : [ "dom" , "es5" , "es2015.promise" ] }, "include" : [ "routes/*" , "utils/*" , "test/*" , "devtools/*" ], "exclude" : [] } |
サーバのトランスパイル用
これでCommon.test()がサーバとブラウザで呼ばれ両方のコンソールに"test"が出力される。