webpack下在index.html使用Vue不起作用

在不用Webpack的情况下:
这个简单的例子是可以的。在浏览器上打开可以看到 "hello"

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.bootcss.com/vue/2.5.15/vue.js"></script>
    <title>Test</title>
</head>

<body>
    <div id="app">
        {{ msg }}
    </div>

    <script> 
        console.log('html init') 
        new Vue({
            el: '#app',
            data: {
                msg: 'hello'
            }
        });
    </script>

</html>

然后在Webpack下,依然是一个简单的例子,就不可行了。浏览器会从"{{ msg }}"变为什么都看不到,console也不报任何错误。

index.html:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Test</title>
</head>

<body>
    <div id="app">
        {{ msg }}
    </div>

    <script> console.log('html init') </script>

</html>

index.js:

import Vue from 'vue';
console.log("init");
window.onload = function () {
    console.log("onload...")
    new Vue({
        el: '#app',
        data: {
            msg: 'hello'
        }
    });
}

package.json:

{
    "name": "vue_sample",
    "version": "1.0.0",
    "main": "index.js",
    "description": "",
    "scripts": {
        "dev": "node node_modules/webpack-dev-server/bin/webpack-dev-server.js",
        "build": "node node_modules/webpack/bin/webpack.js --config webpack.config.production.js"
    },
    "dependencies": {
        "copy-webpack-plugin": "^4.5.1",
        "update": "^0.7.4"
    },
    "devDependencies": {
        "babel-core": "^6.22.1",
        "babel-loader": "^7.1.2",
        "babel-plugin-transform-runtime": "^6.22.0",
        "babel-polyfill": "^6.26.0",
        "babel-preset-env": "^1.2.1",
        "babel-preset-stage-2": "^6.22.0",
        "babel-register": "^6.22.0",
        "babel-runtime": "^6.23.0",
        "webpack": "^4.1.1",
        "webpack-cli": "^2.0.11",
        "webpack-dev-server": "^3.1.1",
        "css-loader": "^0.28.10",
        "file-loader": "^1.1.11",
        "url-loader": "^1.0.1",
        "html-loader": "^0.5.5",
        "html-webpack-plugin": "^3.0.6",
        "vue": "^2.5.15",
        "vue-html-loader": "^1.2.4",
        "vue-loader": "^14.2.1",
        "vue-template-compiler": "^2.5.15"
    },
    "license": "MIT",
    "author": "xxx"
}

webpack 配置

const path  = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const config = {
    entry:'./src/index.js',
    output:{
        path:path.resolve(__dirname,'./dist'), 
        filename:'[name].js',
    },
    resolve:{
        extensions:[".js",".json",".jsx",".css",'.vue']
    },
    module:{
        rules:[
            {
                test:/\.js$/,
                exclude:/(node_modules|bower_components)/,
                use:{
                    loader:'babel-loader',
                    options:{
                        presets:['env'],
                        // 由babel-plugin-transform-runtime提供
                        plugins:['transform-runtime']
                    }
                }
            },
            {test:/\.vue$/,use:'vue-loader'},
            {test:/\.css$/,use:['vue-style-loader','style-loader','css-loader']},
            {test:/\.less$/,use:['style-loader','css-loader','less-loader']},
            {test:/\.scss$/,use:['style-loader','css-loader','sass-loader']},
            {
                test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2|svgz)$/,
                use:{
                    loader: 'file-loader',
                    options: {
                      name: 'assets/images/[name].[ext]?[hash]'
                    }
                }
            },
        ]
           
    },
    devtool: '#eval-source-map',
    plugins:[
        new HtmlWebpackPlugin({template:'./src/index.html'}),
        new webpack.HotModuleReplacementPlugin()
    ],
    devServer:{
        historyApiFallback: true,
        noInfo: true,
        overlay: true,
        port:38080,
        hot:true,
        inline:true,
        open:false
    }
}

module.exports = config;
阅读 3.9k
2 个回答

按照你的分类,分2种情况,第一种是直接引入vue.js, 第二种是使用webpack打包.vue的单文件组件。

  1. 第一种情况下,浏览器打开控制台,Sources里看源码,可以看到{{msg}},而.vue打包后的html,一般body里只有<div #app></div>这种,不包含{{}}, 如果包含{{}}, 会报错。这是因为2种情况下引用的vue版本不一样。
  2. vue大致分2个版本,vue.js 和 vue.runtime.js。官方文档里说了区别,具体你可以自己查看。大致是vue.js = vue.runtime.js + compile。这个compile负责遍历html里的{{}},vue指令(比如v-if),然后翻译成对应的vNode(虚拟DOM)。
  3. 而单文件组件一般用的是vue.runtime.js,用vue.runtime.js有2个好处。因为这本版本不包含compile, 体积更小(好处1),只需要提前用vue-loader将.vue翻译成vNode就行了,这样在客户端浏览器就不用compile后才能看到页面了(好处2, 用户看到页面更快)。这也是为什么这种情况下控制台里html里只有<div id="#app"></div>。
  4. 第二种情况下,你的index.html里,不是直接写<div id="#app"></div>,还含有{{}}, 但是该文件并不会被webpack用vue-loader提前编译,webpack只是通过入口文件把.vue等打包成bundle.js然后放到这个index.html里。所以你的index.html到客户端,是依然是有{{}的。所以最开始会显示为{{}}——以原生html里内容显示,而之后又突然消失,猜测是因为vue.runtime.js运行时,将<div id="#app"></div>里内容进行了覆盖。

控制台输出什么呢
我这边编译出错 应该是没有配置

建议完善webpack配置
clipboard.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题