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"が出力される。