Open8
Snowpack v3を試す
ピン留めされたアイテム
Snowpack v3の試行錯誤ログ
Javascript APIを試す
dev serverを起動する
CLIではなくjsからsnowpackのdev serverを起動する。
server.js
const { startServer, loadConfiguration } = require('snowpack');
async function main() {
const config = await loadConfiguration({}, './snowpack.config.js');
startServer({ config, lockfile: null });
}
main();
$ node server.js
startServer({ config, lockfile: null })
は、2021/01/23現在ドキュメントでは config
だけ設定すれば良いように書かれているが、loackfile
も設定が必要。null
で良いので将来省略可能になりそうな気はする。
SSR
公式サイトのサンプルを動く形にしてみる。
create-snowpack-app
でReactのプロジェクトを作成
1. # typescriptじゃなくてもうごくはず
$ npx create-snowpack-app react-snowpack-ts --template @snowpack/app-template-react-typescript
2. buildする
$ npm build
3. server.jsを作成
ほぼ公式サンプル
expressを追加
$ npm i express
server.js
const fs = require('fs');
const { startServer, loadConfiguration } = require('snowpack');
const app = require('express')();
const React = require('react');
const ReactDOMServer = require('react-dom');
async function main() {
const config = await loadConfiguration({}, './snowpack.config.js');
const server = await startServer({ config, lockfile: null });
const runtime = server.getServerRuntime();
app.use(async (req, res, next) => {
const importedComponent = await runtime.importModule('/dist/App.js');
const MyReactComponent = importedComponent.exports.default;
const html = ReactDOMServer.renderToString(
React.createElement(MyReactComponent, null),
);
const htmlFile = fs.readFileSync('./index.html', 'utf8');
const document = htmlFile.replace(
/<div id="app"><\/div>/,
`<div id="app">${html}</div>`,
);
res.send(document);
});
app.listen('3000', () => {
console.log('http://localhost:3000');
});
}
main();
そもそもReactのSSRをよくわかっていなかった
とりあえず動いた
const { startServer, loadConfiguration } = require('snowpack');
const app = require('express')();
const React = require('react');
const ReactDOMServer = require('react-dom/server');
async function setupSnowpack() {
const config = await loadConfiguration(
{
devOptions: {
// expressをlocalhost:3000で使用しているので
// 起動時snowpackのdev serverを開かない
open: 'none',
// SSRしようとすると react-refresh がないよと怒られ, hmrをオフにすると動いた
hmr: false,
},
},
'./snowpack.config.js',
);
const server = await startServer({ config, lockfile: null });
const runtime = server.getServerRuntime();
return { runtime, server };
}
async function main() {
const { runtime, server } = await setupSnowpack();
app.use(async (req, res) => {
const importedComponent = await runtime.importModule('/dist/Hello.js');
const MyReactComponent = importedComponent.exports.default;
const html = ReactDOMServer.renderToString(
React.createElement(MyReactComponent, null),
);
const { contents } = await server.loadUrl('/index.html');
const htmlFile = Buffer.from(contents).toString('utf8');
const document = htmlFile.replace(
/<div id="root"><\/div>/,
`<div id="root">${html}</div>`,
);
res.send(document);
});
app.listen(3000, () => {
console.log('http://localhost:3000');
});
}
main();
動いてるけどこれなにしてるんだっけ?...
createConfiguration()の返り値
{
root: 'path/to/repo',
plugins: [
{
name: '@snowpack/plugin-esbuild',
resolve: [Object],
load: [AsyncFunction: load],
cleanup: [Function: cleanup]
}
],
alias: {},
exclude: [
'**/node_modules/**/*',
'path/to/repo/build/**/*'
],
routes: [],
devOptions: {
secure: false,
hostname: 'localhost',
port: 8080,
open: 'default',
output: 'dashboard',
hmrDelay: 0,
hmrPort: undefined,
hmrErrorOverlay: true
},
buildOptions: {
out: 'path/to/repo/build',
baseUrl: '/',
metaUrlPath: '/_snowpack',
clean: true,
sourcemap: false,
watch: false,
htmlFragments: false,
ssr: false
},
testOptions: { files: [ '__tests__/**/*', '**/*.@(spec|test).*' ] },
packageOptions: {
source: 'local',
external: [],
packageLookupFields: [],
knownEntrypoints: [],
rollup: { plugins: [] }
},
mount: {
'path/to/repo': { url: '/', static: false, resolve: true }
},
optimize: undefined,
_extensionMap: {
'.mjs': [ '.js' ],
'.jsx': [ '.js' ],
'.ts': [ '.js' ],
'.tsx': [ '.js' ]
}
}
const importModule = await runtime.importModule('/util.js');
const exports = importModule.exports;
exports
でexportされてるものの名前がわからないとアクセスできない。
default export
ある意味名前が決まってるからいいんだけど、名前付きエクスポートはOnject.keys
やらなんやらやってもアクセスできない。
debuggerで見るとgetterになってるのよなぁ。
あるファイルがエクスポートしているものをすべて取得したい
ってのができなさそう。