nuxt-custom-elementsを試してみる

# はじめに

*vue-custom-elements*について調べていた際に、*nuxt-custom-elements*というのを見つけたので試してみる。
*vue-custom-elements*の*nuxt*版っぽいものかな。

Git Hub
https://github.com/GrabarzUndPartner/nuxt-custom-elements

# *nuxt-custom-elements*

READMEの説明(の翻訳)によると、

nuxt-custom-elementsは、vue-custom-elementを使用して単一のコンポーネントをカスタム要素/ web-componentとして公開するNuxt.jsモジュールです。

とのこと。

npmでダウンロードされ始めたのが、2020/1頃で、「Last publish」も「2 months ago」なので、比較的新しいモジュールっぽい。

# *nuxt-custom-elements*のPreview

とりあえず、READMEのPreviewを試してみる。

```
1. Clone this repository
2. Install dependencies using yarn install or npm install
3. Build and start with express npm run start:build
4. Open http://127.0.0.1:3000 in Browser.
```

まず、クローン。

```
> git clone https://github.com/GrabarzUndPartner/nuxt-custom-elements.git
```

それからインストール

```
> yarn install
```

ビルドの前に、*package.json*の*scripts*を見てみる

```package.json
  ...
  "scripts": {
    "dev": "nuxt example",
    "generate": "nuxt generate --config-file example/nuxt.config.js",
    "build": "nuxt build --config-file example/nuxt.config.js",
    "start:build": "yarn build && yarn express-server --dist example/.nuxt/nuxt-custom-elements/dist",
    "lint": "yarn lint:js && yarn lint:css",
    "lint:js": "eslint --ext .js,.vue example lib test",
    "lint:css": "stylelint \"example/**/*.vue\" \"example/**/*.css\", \"lib/**/*.vue\" \"lib/**/*.css\"",
    "release": "yarn test && standard-version && git push --follow-tags && npm publish",
    "express-server": "node ./tools/express-server.js --dist dist/nuxt-custom-elements",
    "test": "yarn lint && jest"
  },
  ...
```

READMEに書いてある"*start:build*"を実行すると、下記コマンドが実行されるらしい。

```
yarn build && yarn express-server --dist example/.nuxt/nuxt-custom-elements/dist
```

つまり、

```
nuxt build --config-file example/nuxt.config.js
```

を実行して、その後に下のようにサーバーを起動する感じですね。

```
node ./tools/express-server.js --dist dist/nuxt-custom-elements
```


元コマンドの最後の*--dist*がどこに効いてくるのか気になるが、
とりあえず、ビルドコマンドを実行してみる。

```
> yarn start:build
```

とくにエラーなくビルドできたようなので、書いてある通りに「*http://127.0.0.1:3000*」にアクセスしてみる。

![error.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/a138b03f-7b52-4edf-4d61-6f242061c598.jpeg)

ん？違うらしい。
コマンド上は下記の通り、特にエラーらしきものは見当たらず、サーバーが正常に起動できているように見える。(やっぱり*--dist*が2回指定されているのは気になるが。。。)

```
...
$ node ./tools/express-server.js --dist dist/nuxt-custom-elements --dist example/.nuxt/nuxt-custom-elements/dist
server listening on http://127.0.0.1:3000 ; dist: dist/nuxt-custom-elements
```

実行している*express-server.js*を見てみると、*dist*で指定したパス以下を静的ファイルとしてホスティングしている模様。

```express-server.js
  ...
  app.use(express.static(dist))
  app.listen(port, host, function () {
    const { address, port } = this.address()
    // eslint-disable-next-line no-console
    console.log(`server listening on http://${address}:${port} ; dist: ${dist}`)
  })
  ...
```
コンソールには、*dist: dist/nuxt-custom-elements*と表示されているので、ここを見てみる。

```
  ...
  - nuxt-custom-elements/
    - component-app-abstract/
      - 0.4de0fb9e8e479190b737.js
      - ... 
      - index.html
    - component-app-bundle/
      - ... 
    - component-app-hash/
      - ... 
    - component-app-history/
      - ... 
    - test.json
  ...
```

うん。確かに「*http://127.0.0.1:3000/*」でアクセスしてもダメそう。
とりあえず、「*http://127.0.0.1:3000/test.json*」でアクセスしてみると、

![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/d0a2b134-a4f0-ef33-23cb-fe05976a517c.jpeg)

なんだかいけそうな気がしてきた。
ということは、「*http://localhost:3000/component-app-abstract*」か。

![example.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/525638b9-694d-c1d0-78f0-aec25eeef214.jpeg)

無事コンポーネント(を呼び出している*index.html*)が表示されました。

コンポーネントの呼び出し方はこんな感じになっているようです。

```index.html
...
  <custom-element-app-abstract base-path="./"></custom-element-app-abstract>
  <script type="text/javascript" src="./component-app-abstract.b773b4f5571aec71cd92.js"></script>
...
```

# *nuxt-custom-elements*を利用してコンポーネントを作ってみる

まずは、*nuxt*公式サイトにある「スクラッチから始める」でnuxt環境を構築。
(*create-nuxt-app*を使うと、逆に訳がわからなくなりそうなので。)

```
> mkdir nuxt-component
> cd nuxt-component
```

package.jsonの設定は適当にこんな感じ

```package.json
{
  "name": "nuxt-component",
  "scripts": {
    "dev": "nuxt"
  }
}
```

*nuxt*をインストールする。

```
> yarn add nuxt
```

*pages*ディレクトリを作って、

```
> mkdir pages
```

*pages/index.vue*を作成

```index.vue
<template>
  <h1>Hello world!</h1>
</template>
```

とりあえず、シンプルなnuxtアプリを起動してみる。

```
> yarn dev
```

![simple.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/bd9ed166-b0bb-7469-a090-f72806ca19ee.jpeg)



シンプルなnuxtアプリが出来たので、*nuxt-custom-elements*のREADMEに従って、セットアップを進めてみる。
*nuxt-custom-elements*のインストール。

```
yarn add nuxt-custom-elements
```

続いて、*nuxt.config.js*を作成

```nuxt.config.js
module.exports = {
  modules: [
    [
      "nuxt-custom-elements",
      {
        polyfill: true,
        entries: [
          {
            name: "ComponentHelloWorld",
            tags: [
              {
                name: "ComponentHelloWorld",
                path: "@/pages/index",
                options: {
                  props: {},
                  shadow: false,
                },
              },
            ],
          },
        ],
      },
    ],
  ],
};
```

※*props*を指定しないとビルド時にエラーになるので、意味ないけど指定しています。
　コード(tag.js)を見る限り、*nuxt-custom-elements*の不具合っぽいです。

*package.json*を編集してビルドや静的ホスティングができるようにする。

```package.json
  ...
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "generate": "nuxt generate"
  },
  ...
```

ビルドしてみる。

```
> yarn build
```

成功すると、*.nuxt*以下に*nuxt-custom-elements*というフォルダが生成され、成果物が格納されている。

※*yarn generate*を実行した場合は、*dist*以下に生成される。

一緒に生成される*index.html*を見ると以下のような感じで呼び出せる模様。

```index.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>component-hello-world</title>
</head>

<body>
  <component-hello-world ></component-hello-world>
  
  <script type="text/javascript" src="./component-hello-world.4254383c620976e0504d.js"></script>
</body>

</html>
```

![nuxt-comp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/e5893566-95d3-a6d5-8c25-c25a2ca6be45.png)

コードはここに置いときました。

https://github.com/yusuke-ka/sample-nce-simple-nuxt

# 気になった点

生成されたjsファイル一式をS3とかで静的ホスティングすれば、外部からも呼び出せるようになるんだろうけど、「4254383c620976e0504d」の部分が余計な気がする。

これ、なんで付いているんだろ。「*component-hello-world.js*」になっていれば、呼び出す側も下のように固定で呼び出せるのに。

```
<body>
  <component-hello-world ></component-hello-world>
　<script type="text/javascript" src="./component-hello-world.js"></script>
</body>
```