ハマった。
環境
$ npm list -g vue-cli E:\node_modules +-- @vue/cli-init@3.0.0-rc.10 | `-- vue-cli@2.9.6 `-- vue-cli@2.9.6 $ npm -version 6.4.1
やりたいこと
- vue cli を使ってテンプレート生成したプロジェクトに、vue用の application コンフィグファイルを作ってRestAPIの接続先サーバーを記述し、アプリケーションで利用したい。
- npm run から起動するビルドスクリプトなどで、NODE_ENVがdevelopmentならdevlopment.jsを読み込み、productionならproduction.jsを読み込みたい。
構成は以下のとおり
vueproject |`- .babelrc |`- .editorconfig |`- .eslintignore |`- .eslintrc.js |`- .gitignore |`- .postcssrc.js |`- build |`- config |`- dist |`- index.html |`- node_modules |`- package-lock.json |`- package.json |`- README.md |`- src | |`- config | | |`- development.js ← | | `- production.js ← | `- componentsとか色々なやつ。この中のコードからconfigを参照 |`- static `- test
設定追加に至るまで
結果的にWebpackにalias を設定する方法を採用。
webpack.base.conf.js
build/webpack.base.conf
に下記を追記
module.exports = { // ... resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } }, // ... } ↓ module.exports = { // ... resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), 'config': resolve(`src/config/${process.env.NODE_ENV}.js`) // 追記 } }, // ... }
npm run dev
や npm run build
時に展開されてwebpackに渡される寸法。
npm run devだけだとでNODE_ENV未設定で解決
どうも vuecli で生成したスクリプトでは、npm run dev
はNODE_ENVにdevelopmentが自動設定される前にwebpackをrunしてしまうらしい。
事前に環境変数 NODE_ENV にdevelopment を設定しておくだけでも解決するが、 自前用のコードであったしものぐさなので、webpack.dev.conf.jsの下記にハードコードで上書きするようにした。
const devWebpackConfig = merge(baseWebpackConfig, { // 下記追記 resolve: { alias: { config: resolve(`src/config/development.js`) } }, // ... })
これで、下記コードでコンフィグが参照できるようになる。
development.js
export default { apiurl: '{protocol}//{host}/api' }
main.js
import Vue from 'vue' import App from './App' import router from './router' import config from 'config' // これ import services from './services/entry' Vue.config.productionTip = false const configMixin = Vue.mixin({ created: function () { this.$config = config for (const key in services) { var tagservice = '$' + key if (this[tagservice]) { console.error(`module name conflicted with $vue.${tagservice}! we take overwrite to ./services/modules.`) } this['$' + key] = services[key] } } }) /* eslint-disable no-new */ new Vue({ el: '#app', router, configMixin, components: { App }, template: '<App/>' })