Vue CLIで作成したVue.jsのプロジェクトで、fsモジュールが読み込めない件

gigazine.net

腸内細菌の多様性は腸を健康にして、心身の健康にもつながっています。腸内細菌はまとめて「腸内細菌叢(そう)」と呼ばれ、細菌が種類ごとに腸の壁に張り付いている様子が、まるで花が品種ごとに植えられた花畑のようであることから「腸内フローラ」とも呼ばれるのですが、この腸内フローラの多様性の改善にビールが役立つ可能性を指摘する研究が発表されています。

ビールが腸内フローラの多様性改善に役立つかもしれないという研究結果 - GIGAZINE

⇧ amazing...

Module not found: Error: Can't resolve 'fs' inって言われてもね...

事の発端は、

github.com

Microsoftさんの公式のサンプルを試そうとして、

Failed to compile with 1 error
Module not found: Error: Can't resolve 'fs' in

⇧ ってエラーが出たのね。

で、調べてみたんだけど、

nodejs.org

Source Code: lib/fs.js

The node:fs module enables interacting with the file system in a way modeled on standard POSIX functions.

https://nodejs.org/api/fs.html#file-system

⇧ fsってモジュールは、Node.jsがインストールされてればデフォルトで利用できるらしいですと。

で、自分の環境では、Vue CLIでVue.jsのプロジェクトを作成していることから、Node.jsをインストール済みですと。

つまり、fsモジュールは利用できるはずであると。

なのに、fsモジュールが見つからないと...

Vue CLIで作成したVue.jsのプロジェクトで、fsモジュールが読み込めない件

で、いろいろ情報を探ってみて、

stackoverflow.com

⇧ どうも、海外でも話題になっておりました...

で、Vue CLIで作成するVue.jsのプロジェクトってNode.jsがないと作れないんだけど、内部的に、webpackeを利用しているっぽい...

webpackの公式のドキュメントによると、

webpack.js.org

Webpack 5 no longer polyfills Node.js core modules automatically which means if you use them in your code running in browsers or alike, you will have to install compatible modules from npm and include them yourself. Here is a list of polyfills webpack has used before webpack 5:

https://webpack.js.org/configuration/resolve/#resolvefallback

module.exports = {
  //...
  resolve: {
    fallback: {
      assert: require.resolve('assert'),
      buffer: require.resolve('buffer'),
      console: require.resolve('console-browserify'),
      constants: require.resolve('constants-browserify'),
      crypto: require.resolve('crypto-browserify'),
      domain: require.resolve('domain-browser'),
      events: require.resolve('events'),
      http: require.resolve('stream-http'),
      https: require.resolve('https-browserify'),
      os: require.resolve('os-browserify/browser'),
      path: require.resolve('path-browserify'),
      punycode: require.resolve('punycode'),
      process: require.resolve('process/browser'),
      querystring: require.resolve('querystring-es3'),
      stream: require.resolve('stream-browserify'),
      string_decoder: require.resolve('string_decoder'),
      sys: require.resolve('util'),
      timers: require.resolve('timers-browserify'),
      tty: require.resolve('tty-browserify'),
      url: require.resolve('url'),
      util: require.resolve('util'),
      vm: require.resolve('vm-browserify'),
      zlib: require.resolve('browserify-zlib'),
    },
  },
};

https://webpack.js.org/configuration/resolve/#resolvefallback

⇧ とあって、webpackeのバージョン5より前は、webpackが上記のNode.jsの主要なモジュールについては、自動的に読み込んでくれていたらしい。

ただ、どっちにしろ、fsモジュールは無いやんけ...

とりあえず、

stackoverflow.com

⇧ 上記サイト様を参考に、モジュールをインストールして試してみる。

うん...やはりというかエラー変わらんわな...

最早、

qiita.com

stackoverflow.com

stackoverflow.com

⇧ 力業で対応するしかないっぽい...

で、試してみたものの、Vue CLIで作成したVue.jsのプロジェクトだと駄目っぽいですね、解決したって人の話も一部分しかコード載せてくれてないから、差分の比較のしようがないので本当に動いたんか検証のしようがない...

で、どうやら、

//const path = require("path");
//const resolve = (dir) => path.join(__dirname, dir);
//const vueSrc = "src/";

const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");

//const { defineConfig } = require("@vue/cli-service");
const webpack = require("webpack");
//const nodeExternals = require("webpack-node-externals");

const serverConfig = {
  chainWebpack: (config) => {
    config.plugin("polyfills").use(NodePolyfillPlugin);
    config.target("node");
    //config.externals(nodeExternals({ allowlist: /\.(css|vue)$/ }));
  },
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        Buffer: ["buffer", "Buffer"],
      }),
      new webpack.ProvidePlugin({
        process: "process/browser",
      }),
    ],
    resolve: {
      fallback: {
        os: require.resolve("os-browserify/browser"),
        url: require.resolve("url/"),
        crypto: require.resolve("crypto-browserify"),
        https: require.resolve("https-browserify"),
        http: require.resolve("stream-http"),
        assert: require.resolve("assert/"),
        stream: require.resolve("stream-browserify"),
        buffer: require.resolve("buffer"),
        fs: require.resolve("fs"),
      },
    },
  },
  css: {
    loaderOptions: {
      scss: {
        additionalData: `
          @use "@/assets/common/scss/color.scss";
          @use "@/assets/common/scss/feature.scss";
         `,
      },
    },
  },
  transpileDependencies: ["vuetify"],
};

// const clientConfig = {
//   chainWebpack: (config) => {
//     config.plugin("polyfills").use(NodePolyfillPlugin);
//     config.target("web");
//   },
//   //settings: {
//   //  "vetur.useWorkspaceDependencies": true,
//   //  "vetur.experimental.templateInterpolationService": true,
//   //},
//   css: {
//     loaderOptions: {
//       scss: {
//         additionalData: `
//           @use "@/assets/common/scss/color.scss";
//           @use "@/assets/common/scss/feature.scss";
//          `,
//       },
//     },
//   },

// chainWebpack: (config) => {
//   config.resolve.alias
//     .set("@", resolve("src"))
//     .set("assets", resolve("src/assets"))
//     .set("components", resolve("src/components"))
//     .set("views", resolve("src/views"))
//     .set("modules", resolve(vueSrc.concat("modules")));
//   config.resolve.extensions
//     .merge([".mjs", ".js", ".jsx", ".vue", ".json", ".wasm", ".ts"])
//     .end();
// },
// };

module.exports = serverConfig;

⇧ config.target(node)を設定すれば、コンパイルは通るようになるんだけど、ブラウザの画面が真っ白になる...

う~ん、config.target(node)を設定すると、ブラウザ側で不都合が起こるというね...

ちなみに、自分の環境のpackage.jsonは以下のようになっております。

{
  "name": "my-project-vue",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "vue": "^2.6.14",
    "vue-class-component": "^7.2.3",
    "vue-property-decorator": "^9.1.2",
    "vue-router": "^3.5.1"
  },
  "devDependencies": {
    "@types/node": "^18.0.0",
    "@types/video.js": "^7.3.40",
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-plugin-typescript": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "@vue/eslint-config-typescript": "^9.1.0",
    "axios": "^0.26.1",
    "element-ui": "^2.15.8",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-vue": "^8.0.3",
    "fs": "0.0.1-security",
    "node-polyfill-webpack-plugin": "^2.0.0",
    "prettier": "^2.4.1",
    "sass": "^1.32.7",
    "sass-loader": "^12.0.0",
    "typescript": "~4.5.5",
    "v-idle": "^0.2.1",
    "video.js": "^7.19.2",
    "vue-template-compiler": "^2.6.14",
    "webpack-node-externals": "^3.0.0"
  }
}

なんか、

webpack.js.org

⇧ クライアント用とサーバー用で設定を分けるしかないっぽいんだけど、

Vue CLIでのプロジェクトの場合、

github.com

⇧ Vueのフレームワークは無力であるらしい...

Vue.js、TypeScriptとも相性悪いですし、有益な情報が見つからん...

いまのところ、

bradfrost.com

⇧ 上記サイト様にあるように、

  • front-of-the-front-end
  • back-of-the-front-end

で、完全にフロントエンド側のプロジェクトを分けて、「back-of-the-front-end」側でfsモジュール使う感じにするしかないんかな...

あとは、「SSR(Server Side Rendering)」がVue.jsでもできるらしく、

v3.ja.vuejs.org

clientManifest の生成

サーバ用のバンドルに加えて、クライアント用のビルドマニフェストも生成できます。クライアント用マニフェストとサーバ用バンドルによって、レンダラーは サーバとクライアント両方の ビルドの情報を持つことになります。

ビルド設定 | Vue.js

⇧ ってあるんだけど、肝心のclientManifestの生成の方法について説明がない...

まぁ、Vue CLIで作成したVue.jsのプロジェクトでwebpackを利用してる場合は、fsモジュールは使えないって考えといた方が良さそうですかね...

Vue CLIでwebpack使っていて、画面表示とかも考えてfsモジュールを利用するとなると、構成が複雑になってくる気がしますかね...

Vue CLIがいけてないだけなのかな?

2022年6月27日(月)追記:↓ ここから

調べたところ、

tech-blog.optim.co.jp

⇧ 上記サイト様によりますと、Express.jsなるものの力を借りれば、おそらくfsモジュールを利用できるっぽい気はするのだけど、

codeanatomy.code.blog

stackoverflow.com

⇧ Spring Bootと同時に利用できるのかが分からん...

2022年6月27日(月)追記:↑ ここまで

今回はこのへんで。