简单用webpack搭建vue开发环境

准备工作

环境

  • node.js(v10.15.1)

初始化项目

npm init --yes

依赖包

  • webpack
  • webpack-cli
  • webpack-dev-server
  • html-webpack-plugin
  • vue
  • vue-router
  • vue-loader
  • vue-template-compiler
  • style-loader
  • css-loader
  • file-loader

安装依赖包

npm install webpack webpack-cli webpack-dev-server html-webpack-plugin vue vue-router vue-loader vue-template-compiler style-loader css-loader file-loader --save-dev

目录结构

webpack_demo
  |- /config
    |- index.js
  |- /src
    |- /component
      |- /Index
        |- Index.vue
    |- /router
      |- index.js
      |- router.config.js
    |- App.vue
    |- index.html
    |- main.js
  |- package.json

文件内容

config/index.js

const path = require('path');
const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: path.join(__dirname, '../src/main.js'),
    devtool: 'source-map',
    devServer: {
        publicPath: '/',
        hot: true
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, '../src/index.html'),
            title: '测试'
        }),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new VueLoaderPlugin({})
    ],
    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: 'bundle.js',
        publicPath: '/'
    },
    module: {
        rules: [{
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }, {
            test: /\.vue$/,
            use: ['vue-loader']
        }, {
            test: /\.(?:png|svg|jpg|gif)/,
            use: ['file-loader']
        }]
    },
    resolve: {
        // 设置别名 引入vue自动变成引入vue/dist/vue.esm.js
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    }
}

src/component/Index/Index.vue

<template>
    <div id="index">
        <h1>{{msg}}</h1>
    </div>
</template>
<script>
export default {
    data () {
        return {
            msg: 'hello baozhongyao'
        }
    },
    mounted () {
        console.log('hello');
    }
}
</script>
<style>
    #index {
        color: red;
    }
</style>

src/router/index.js

import Index from '../component/Index/Index.vue';

export default {
    routes: [{
        path: '/index',
        component: Index
    }, {
        path: '*',
        redirect: '/index'
    }]
}

src/router/router.config.js

import Index from '../component/Index/Index.vue';

export default {
    routes: [{
        path: '/index',
        component: Index
    }, {
        path: '*',
        redirect: '/index'
    }]
}

src/App.vue

<template>
    <div id="app">
        <router-view></router-view>
    </div>
</template>
<script>
export default {
    
}
</script>
<style>

</style>

src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vue-demo</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>

src/main.js

import Vue from 'vue';
import router from './router';
import App from './App.vue';

new Vue({
    el: '#app',
    template: '<App/>',
    components: {
        App: App
    },
    router: router
});

package.json

{
  "name": "vue-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --open --progress --config config/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^2.1.1",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "style-loader": "^0.23.1",
    "vue-loader": "^15.7.0",
    "vue-template-compiler": "^2.6.10",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.3.0",
    "webpack-dev-server": "^3.2.1"
  },
  "dependencies": {
    "vue": "^2.6.10",
    "vue-router": "^3.0.2",
  }
}

启动

npm run dev

填坑统计

没有安装vue-template-compiler

报错信息

ERROR in ./src/App.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
[vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options. @ ./src/main.js 2:0-28 8:13-16
 @ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/main.js

ERROR in ./src/App.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
 @ ./src/main.js 2:0-28 8:13-16
 @ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/main.js

ERROR in ./src/App.vue
Module build failed (from ./node_modules/vue-loader/lib/index.js):
TypeError: Cannot read property 'parseComponent' of undefined
    at parse (C:\Users\nesxiaogu\Desktop\vue-demo\node_modules\@vue\component-compiler-utils\dist\parse.js:14:23)
    at Object.module.exports (C:\Users\nesxiaogu\Desktop\vue-demo\node_modules\vue-loader\lib\index.js:67:22)
 @ ./src/main.js 2:0-28 8:13-16
 @ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/main.js

解决办法

npm install vue-template-compiler --save-dev

没有配置vue-loader-plugin

报错信息

ERROR in ./src/App.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
 @ ./src/main.js 2:0-28 10:13-16
 @ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/main.js

ERROR in ./src/component/Index/Index.vue?vue&type=style&index=0&lang=css& 17:0
Module parse failed: Unexpected character '#' (17:0)
You may need an appropriate loader to handle this file type.
|
|
> #index h1 {
|     color: red;
| }
 @ ./src/component/Index/Index.vue 4:0-65
 @ ./src/router/router.config.js
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/main.js

ERROR in ./src/App.vue?vue&type=template&id=7ba5bd90& 2:0
Module parse failed: Unexpected token (2:0)
You may need an appropriate loader to handle this file type.
|
> <div id="#app">
|     <router-view></router-view>
| </div>
 @ ./src/App.vue 1:0-82 10:2-8 11:2-17 30:4-35:6 30:66-35:5 32:16-22 33:25-40
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/main.js

ERROR in ./src/component/Index/Index.vue?vue&type=template&id=53ffb37a& 2:0
Module parse failed: Unexpected token (2:0)
You may need an appropriate loader to handle this file type.
|
> <div id="index">
|     <h1>{{msg}}</h1>
| </div>
 @ ./src/component/Index/Index.vue 1:0-84 11:2-8 12:2-17 31:4-36:6 31:68-36:5 33:16-22 34:25-40
 @ ./src/router/router.config.js
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/main.js

解决办法

  • config/index.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
+ const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
    entry: path.join(__dirname, '../src/main.js'),
    devServer: {
        publicPath: '/',
        hot: true
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title: 'vue-demo-hahaha',
            template: path.join(__dirname, '../src/index.html')
        }),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin(),
+       new VueLoaderPlugin()
    ],
    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: 'bundle.js',
        publicPath: '/'
    },
    module: {
        rules: [{
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }, {
            test: /\.vue$/,
            use: ['vue-loader']
        }, {
            test: /\.(?:png|svg|jpg|gif)$/,
            use: ['file-loader']
        }]
    }
}

Vue两种代码形式的问题

vue有两种形式的代码 compiler(模板)模式和runtime模式(运行时),vue模块的package.json的main字段默认为runtime模式, 指向了"dist/vue.runtime.common.js"位置

compiler模式实例化Vue写法

// compiler
new Vue({
	el: '#app',
	router: router,
	store: store,
	template: '<App/>',
	components: { App }
});

runtime模式实例化Vue写法

// runtime
new Vue({
	el: '#app',
	router,
	store,
	render: h => h(App)
});

总结

  • 上面提到Vue模块默认使用的是runtime模式,如果我们实例化的时候使用的是compiler的写法就会包下面的警告
vue.runtime.esm.js:620 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

(found in <Root>)

解决方法

将实例化写法改成runtime实例化的写法

引入compiler模式对应的js

使用这种方法需要将所有引入vue地方都要改成同样的路径,不然可能会出问题,比如说在src/main.js里面引用的是vue/dist/vue.esm.jssrc/router/index.js里面引用的是vue,这样就会报错,报错信息如下

  • 报错信息
[Vue warn]: Unknown custom element: <router-view> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

found in

---> <App> at src/App.vue
       <Root>
  • 引入方式
import Vue from 'vue/dist/vue.esm.js'

设置webpack路径别名(推荐)

// webpack 配置添加如下
resolve: {
    // 设置别名 引入路径含有vue结尾的vue三个字符自动转化成vue/dist/vue.esm.js
    alias: {
        'vue$': 'vue/dist/vue.esm.js'
    }
}

填坑查询的帖子地址

猜你喜欢

转载自blog.csdn.net/nesxiaogu/article/details/88824553