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
export class Common { public static test() { console.log("test") } }
index.pug
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="https://unpkg.com/element-ui/lib/theme-chalk/index.css") link(rel='stylesheet', href='/stylesheets/style.css') //- link(rel="icon" type="image/png" href="/images/favicon.png") script(src="https://cdn.jsdelivr.net/npm/vue") script(src="https://unpkg.com/element-ui/lib/index.js") body script(src="./javascripts/dist/index.built.js") h1 サーバ・クライアント共通化
サーバ側の処理
b_index.ts
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
import { Common } from "./../../common/common" Common.test()
サーバ・フロントそれぞれでCommon.test()を呼び出している。
Webpack設定ファイル
webpack.config.js
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
{ "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
{ "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"が出力される。