在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ webpack Vue多文件入口 引發(fā)了不可描述的異常!

webpack Vue多文件入口 引發(fā)了不可描述的異常!

使用webpack + Vue 開發(fā)多頁面應(yīng)用

入口包含一個公用的common.js 和 對應(yīng)頁面的js文件

// common.js
import Vue from 'vue'
import Toast from './plugins/toast'
import Popup from './components/popup'
...
Vue.use(Toast)
Vue.use(Popup)

window.Vue = Vue
// 對應(yīng)頁面的js
import App from './App.vue'

new window.Vue({
  template: '<App/>',
  components: {App}
}).$mount('#app')

我在App.vue里調(diào)用this.$toast(...) 錯誤提示: this.$toast不存在 其實我已經(jīng)Vue.use(Toast)注冊了。

如果我只有一個文件入口能調(diào)用this.$toast

我想了想 可能是Vue這對象的問題 我又改了下代碼

// common.js
import Toast from './plugins/toast'
import Popup from './components/popup'
...

window.VueInstall = function (Vue) {
    Vue.use(Toast)
    Vue.use(Popup)
    ...
}
// 對應(yīng)頁面的js
import Vue from 'vue'
import App from './App.vue'

window.VueInstall(Vue)

new Vue({
  template: '<App/>',
  components: {App}
}).$mount('#app')

經(jīng)過了修改,現(xiàn)在能在成功調(diào)用this.$toast,但是卻提示我popup這個組件不存在,因為toast依賴popup組件,toast內(nèi)部沒有單獨注冊popup這局部組件。App.vue里我寫入<popup></popup>能成功渲染,就只有$toast這里會提示popup組件不存在。這是為什么呢?我只有在toast組件內(nèi)注冊popup的局部組件才能跑通,why? 我不是注冊了全局組件么?

我應(yīng)該如果解決目前這個問題呢?求解答?
還有一個問題,經(jīng)過打包出來發(fā)現(xiàn) common.js 和 對應(yīng)頁面.js 的文件內(nèi)都把vue.js給打包進去了。這該怎么解決呢?
因為項目限制,不能做單頁面,只能做多頁面。

最后附上多頁面的webpack配置

const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = require('../package.json')

/**
 * 獲取絕對路徑
 * @param dir
 * @returns {string|*}
 */
function resolve (dir) {
  return path.join(process.cwd(), dir)
}
/**
 * vue css加載器
 * @returns {
 *  {css: *, scss: *}
 * }
 */
function cssLoaders () {
  const cssLoader = {
    loader: 'css-loader',
    options: {
      minimize: process.env.NODE_ENV !== 'development',
      sourceMap: false
    }
  }

  function generateLoaders (loader, loaderOptions) {
    const loaders = [cssLoader]
    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, {
          sourceMap: false
        })
      })
    }

    if (process.env.NODE_ENV !== 'development') {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader'
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
  }

  return {
    css: generateLoaders(),
    scss: generateLoaders('sass')
  }
}

const pages = fs.readdirSync(resolve('src/pages'))

module.exports = function ({plugins, htmlPluginOptions}) {
  const htmlPlugins = []
  const entrys = {
    'common': './src/common.js'
  }

  for (const name of pages) {
    const entry = `./src/pages/${name}/index.js`
    entrys[name] = [entry]
    if (process.env.NODE_ENV === 'development') entrys[name].push('./build/dev-client')
    htmlPlugins.push(new HtmlWebpackPlugin(Object.assign({
      filename: process.env.NODE_ENV === 'development' ? name + '.html' : resolve(config.id + '/' + name + '.html'),
      template: `src/pages/${name}/index.html`,
      inject: true,
      chunks: ['common', name],
      hash: false,
      chunksSortMode (a, b) {
        return a.id > b.id ? 1 : -1
      },
      config: {
        env: process.env.NODE_ENV
      }
    }, htmlPluginOptions)))
  }

  const chunks = Object.values(entrys)
  htmlPlugins.push(
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendors',
      chunks: chunks,
      minChunks: chunks.length
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common',
      chunks: ['common']
    })
  )

  return {
    entry: entrys,
    output: {
      path: resolve(config.id),
      filename: 'static/js/[name].js?[hash:7]',
      publicPath: `/`,
      chunkFilename: 'static/js/[id].[hash].js'
    },
    resolve: {
      extensions: ['.vue', '.js'],
      alias: {
        '@': resolve('public/src'),
        'vue$': 'vue/dist/vue.esm.js'
      }
    },
    devtool: process.env.NODE_ENV !== 'development' ? false : '#cheap-module-eval-source-map',
    module: {
      rules: [
        {
          test: /\.vue$/,
          loader: 'vue-loader',
          options: {
            loaders: cssLoaders()
          }
        },
        {
          test: /\.css$/,
          use: process.env.NODE_ENV !== 'development' ? ExtractTextPlugin.extract('css-loader') : ['style-loader', 'css-loader']
        },
        {
          test: /\.js$/,
          loader: 'babel-loader',
          include: [resolve('src')]
        },
        {
          test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: `[path][name].[ext]?[hash:7]`
          }
        }
      ]
    },
    plugins: htmlPlugins.concat(plugins)
  }
}
回答
編輯回答
逗婦惱

@NextStack

App.vue:

<template>
  <div>
    <popup v-model="visible">
      我是popup組件
    </popup>
  </div>
</template>
<script>
  export default {
    data () {
      return {
        visible: true
      }
    },
    created () {
      this.$toast('啦啦啦!我是賣報的小當家。')
    }
  }
</script>
<style lang="scss" rel="stylesheet/scss" type="text/scss">
</style>

運行的效果:
圖片描述

popup全局組件已經(jīng)注冊成功了,上面效果圖就說明了。但是toast里面引用就報錯。
圖片描述

編譯出的html文件:

...
<script type="text/javascript" src="/static/js/common.js?f56345f"></script>
<script type="text/javascript" src="/static/js/store.js?f56345f"></script>
...

common.js是公共js文件,store.js是對應(yīng)頁面的js文件。common.jsstore.js里面都引用了.vue文件,導致2個加入了vue.esm.js這文件,相當于存在2個Vue對象,所有我就嘗試了我提問時寫的2種寫法(保證common.js 和 store.js使用的是同一個Vue對象),依然差強人意,需要各位幫忙看看如何解決這問題。

當然改為單頁面,單文件入口就不會出現(xiàn)以上問題。因項目需求只能做多頁面,多入口。


補充:
目前已經(jīng)解決問題經(jīng)NextStack的提點,使用CommonChunkPlugin成功解決問題,代碼修改如下:

// common.js
import Toast from './plugins/toast'
import Popup from './components/popup'

export default function (Vue) {
  Vue.use(Toast)
  Vue.use(Popup)
}
// 對應(yīng)頁面的js
import Vue from 'vue'
import install from '../../common'
import App from './App.vue'

install(Vue)

new Vue({
  template: '<App/>',
  components: {App}
}).$mount('#app')

代碼如上修改,并且webpack設(shè)置里移除common這個入口。這樣只會出現(xiàn)一個vue對象,然后使用CommonChunkPlugin把公用代碼給提取出來。

webpack設(shè)置:

const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = require('../package.json')

/**
 * 獲取絕對路徑
 * @param dir
 * @returns {string|*}
 */
function resolve (dir) {
  return path.join(process.cwd(), dir)
}
/**
 * vue css加載器
 * @returns {
 *  {css: *, scss: *}
 * }
 */
function cssLoaders () {
  const cssLoader = {
    loader: 'css-loader',
    options: {
      minimize: process.env.NODE_ENV !== 'development',
      sourceMap: false
    }
  }

  function generateLoaders (loader, loaderOptions) {
    const loaders = [cssLoader]
    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, {
          sourceMap: false
        })
      })
    }

    if (process.env.NODE_ENV !== 'development') {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader'
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
  }

  return {
    css: generateLoaders(),
    scss: generateLoaders('sass')
  }
}

const pages = fs.readdirSync(resolve('src/pages'))

module.exports = function ({plugins, htmlPluginOptions}) {
  const htmlPlugins = []
  const entrys = {
    // 'common': './src/common.js'
  }

  for (const name of pages) {
    const entry = `./src/pages/${name}/index.js`
    entrys[name] = [entry]
    if (process.env.NODE_ENV === 'development') entrys[name].push('./build/dev-client')
    htmlPlugins.push(new HtmlWebpackPlugin(Object.assign({
      filename: process.env.NODE_ENV === 'development' ? name + '.html' : resolve(config.id + '/' + name + '.html'),
      template: `src/pages/${name}/index.html`,
      inject: true,
      // chunks: ['common', name],
      chunks: ['common.js', name],
      hash: false,
      chunksSortMode (a, b) {
        return a.id < b.id ? 1 : -1
      },
      config: {
        env: process.env.NODE_ENV
      }
    }, htmlPluginOptions)))
  }

  const chunks = Object.values(entrys)
  htmlPlugins.push(
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendors',
      chunks: chunks,
      minChunks: chunks.length
    })
    // new webpack.optimize.CommonsChunkPlugin({
    //   name: 'common',
    //   chunks: ['common']
    // })
  )

  return {
    entry: entrys,
    output: {
      path: resolve(config.id),
      filename: 'static/js/[name].js?[hash:7]',
      publicPath: `/`,
      chunkFilename: 'static/js/[id].[hash].js'
    },
    resolve: {
      extensions: ['.vue', '.js'],
      alias: {
        '@': resolve('public/src'),
        'vue$': 'vue/dist/vue.esm.js'
      }
    },
    devtool: process.env.NODE_ENV !== 'development' ? false : '#cheap-module-eval-source-map',
    module: {
      rules: [
        {
          test: /\.vue$/,
          loader: 'vue-loader',
          options: {
            loaders: cssLoaders()
          }
        },
        {
          test: /\.css$/,
          use: process.env.NODE_ENV !== 'development' ? ExtractTextPlugin.extract('css-loader') : ['style-loader', 'css-loader']
        },
        {
          test: /\.js$/,
          loader: 'babel-loader',
          include: [resolve('src')]
        },
        {
          test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: `[path][name].[ext]?[hash:7]`
          }
        }
      ]
    },
    // plugins: htmlPlugins.concat(plugins)
    plugins: htmlPlugins.concat(plugins).concat([new webpack.optimize.CommonsChunkPlugin('common.js')])
  }
}

被注釋掉的代碼,是原配置。已經(jīng)成功解決了,非常感謝NextStack

2018年2月14日 06:37
編輯回答
夏木

不如直接用 vue 命令行的 webpack 項目模板創(chuàng)建項目,然后稍微修改一下 webapck 的配置文件

或者 https://segmentfault.com/l/15...

2018年6月9日 10:48
編輯回答
浪婳

有解決方案了嗎?

2017年7月7日 04:01
編輯回答
你好胸

沒有App.vue的代碼?.vue文件最終也是構(gòu)建成一個VUE實例,你在App.vue中調(diào)用$toast時不能確定插件是否注冊完成。另外webpack打包,需要使用CommonChunkPlugin來拆分代碼

2018年9月21日 23:42