从零开始用 webpack 搭建一个 Vue 项目

版权声明:本文为博主原创文章,博主不会以任何方式收取查看费用,欢迎大家转载。 https://blog.csdn.net/guozhangqiang/article/details/89497827

首先新建一个文件夹,比如 my-first-webpack ,初始化项目,得到一个 package.json 文件

npm init

然后安装  vue、webpack、webpack-dev-server

npm install vue --save
npm install webpack webpack-dev-server --save-dev

这里,我用的是 webpack4,还需要另外安装

npm install webpack-cli -g
npm install -D webpack-cli 

用脚手架搭建的项目有一个 index.html 文件,所以,在这里,我们也在根目录下新建一个 index.html 文件,内容大致如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>my-first-webpack</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

然后在新建一个 js 文件,取名为 webpack.config,初始内容如下:

var path = require('path');
var webpack = require('webpack');

module.exports = {};

最后,再仿造脚手架搭建的项目结构,新建一个 src 文件夹,下面再新建一个 main.js 文件

项目结构目录大致如下:

现在,我们需要对 webpack.config 进行基本的配置,必不可少的入口 entry,出口 output,具体代码如下:

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: './src/main.js', //项目入口文件
    output: {
        path: path.resolve(__dirname, './dist'), //项目打包后的文件路径
        publicPath: '/dist/', // 通过devServer访问路径,见下方devServer
        filename: 'custom.js' // 打包后的文件名,可自定义名称
    },
    devServer: {
        historyApiFallback: true,
        overlay: true
    }
};

配好后,还要对 package.json 进行修改

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --open --hot",
    "build": "webpack --progress --hide-modules"
 },

其中,dev 是当你执行 npm run dev 时,webpack 会执行的语句,build 就是当你执行 npm run build 时,webpack 执行的语句

现在,进入核心部分的配置:

1、引入 vue ,在 webpack.config 文件中,添加

resolve: {
    alias: {
        'vue$': 'vue/dist/vue.esm.js'
    }
}

和 devServer 同级,我就直接放在 devServer 下面的

webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: './src/main.js', //项目入口文件
    output: {
        path: path.resolve(__dirname, './dist'), //项目打包后的文件路径
        publicPath: '/dist/', // 通过devServer访问路径,见下方devServer
        filename: 'custom.js' // 打包后的文件名,可自定义名称
    },
    devServer: {
        historyApiFallback: true,
        overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    }
};

main.js

import Vue from 'vue';

var app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!'
    }
});

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>my-first-webpack</title>
</head>
<body>
<div id="app">
    {{message}}
</div>
<script src="./dist/custom.js"></script>
<!-- built files will be auto injected -->
</body>
</html>

这里细心的同学就会发现,index.html 文件引入了一个外部js文件,这个文件是刚才我们自定义名称叫 custom 的 js 文件,所以需要先执行 npm run build 才会有这个文件,接着再执行 npm run dev ,这样浏览器会直接打开一个网页,网页内容就是 “ Hello Vue! ” 

2、引入 css 等样式

在 src 文件夹下新建一个 styles 文件夹,再在 styles 文件夹下新建一个 common.css 文件,添加一个全局样式,最后再在 main.js 里面引入该文件

common.css

body{
    color:red
}

这样,你会发现程序报错,是因为 webpack 默认只支持 js 的模块化,如果需要把其他文件也当成模块引入,就需要相对应的  loader 解析器,所以这里我们下载 css 的解析器

npm install node-sass css-loader vue-style-loader sass-loader --save-dev

下载完成后,重新配置一下 webpack.config 文件

webpack.config

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: './src/main.js', //项目入口文件
    output: {
        path: path.resolve(__dirname, './dist'), //项目打包后的文件路径
        publicPath: '/dist/', // 通过devServer访问路径,见下方devServer
        filename: 'custom.js' // 打包后的文件名,可自定义名称
    },
    devServer: {
        historyApiFallback: true,
        overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ]
            }
        ]
    }
};

这样重启项目你就会发现,样式生效了。因为项目有时不仅仅只要 css 样式,那么其他的配置也是一个道理

module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader'
                ],
            },
            {
                test: /\.sass$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader?indentedSyntax'
                ],
            }
        ]
    }

这里要说明一下,因为我们这里用 vue 开发,所以使用 vue-style-loader,其他情况使用 style-loader

3、使用babel转码

ES6 的语法大多数浏览器依旧不支持,所以我们需要引入 bable 把 ES6 转码成 ES5 语法,这样我们就可以项目中使用 ES6 的最新特性了

因为我这使用的是 webpack4 ,舍弃了 babel-*-* ,改成了 @babel/*-* ,同样插件也舍弃了 babel-plugin-* ,改成 @babel/plugin-* ,所以我们应该使用以下命令

npm install @babel/core
npm install @babel/preset-env
npm install @babel/plugin-transform-runtime
npm install babel-polyfill --save-dev

首先,在项目根目录下新建 .babelrc 文件

{
  "presets": ["@babel/preset-env"],
  "plugins": [
    "@babel/plugin-transform-runtime"
  ]
}

再在 webpack.config 添加一个 loader

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: ['babel-polyfill','./src/main.js'], //项目入口文件
    output: {
        path: path.resolve(__dirname, './dist'), //项目打包后的文件路径
        publicPath: '/dist/', // 通过devServer访问路径,见下方devServer
        filename: 'custom.js' // 打包后的文件名,可自定义名称
    },
    devServer: {
        historyApiFallback: true,
        overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader'
                ],
            },
            {
                test: /\.sass$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader?indentedSyntax'
                ],
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            }
        ]
    }
};

exclude 表示忽略 node_modules 文件夹下的文件,不用转码,不要忽略 entry ,这里也需要做一下处理

然后,我们就可以写一些 ES6 的语法来检测

main.js

import Vue from 'vue';
import './styles/common.css'
var app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!'
    },
    created() {
        console.log(...[1, 2, 3])
    }
});

重启项目,我们就能看见控制台输出的内容了

4、引入图片资源

把图片也当成模块引入

npm i file-loader --save-dev

再在 webpack.config 添加一个 loader

{
    test: /\.(png|jpg|gif|svg)$/,
    loader: 'file-loader',
    options: {
        name: '[name].[ext]?[hash]'
    }
}

在 src 文件夹下新建一个 images 文件夹,放一张图片 img.jpg

main.js

import Vue from 'vue';
import './styles/common.css'

Vue.component('my-component', {
    template: '<img :src="url" />',
    data() {
        return {
            url: require('./images/img.jpg')
        }
    }
});

var app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!',
    },
    created() {
        console.log(...[1, 2, 3])
    }
});

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>my-first-webpack</title>
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
<div id="app" v-cloak>
    {{message}}
    <my-component></my-component>
</div>
<script src="./dist/custom.js"></script>
<!-- built files will be auto injected -->
</body>
</html>

这样就可以看见图片正常显示了

5、单文件组件

在实际项目里,我们都是使用的 .vue 文件,也就是单文件组件

npm install vue-loader
npm install vue-template-compiler

再在 webpack.config 添加一个 loader

{
    test: /\.vue$/,
    loader: 'vue-loader',
    options: {
        loaders: {
            'scss': [
                'vue-style-loader',
                'css-loader',
                'sass-loader'
            ],
            'sass': [
                'vue-style-loader',
                'css-loader',
                'sass-loader?indentedSyntax'
            ]
        }
    }
}

在 src 目录下新建一个 App.vue

<template>
    <div id="app">
        <input type="text" v-model="message">
        <span>{{ message }}</span>
        <img src="./images/img.jpg">
    </div>
</template>

<script>
    export default {
        name: "App",
        data () {
            return {
                message: 'Hello Vue!',
            }
        },
        created() {
            console.log(...[1, 2, 3])
        },
    }
</script>

<style scoped>

</style>

main.js

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

import './styles/common.css'

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

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>my-first-webpack</title>
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
<div id="app"></div>
<script src="./dist/custom.js"></script>
<!-- built files will be auto injected -->
</body>
</html>

重头戏来了,当你启动项目会发现报错,是因为 vue-loader@15.* 之后除了必须带有 VueLoaderPlugin,所以,你还需要

npm install vue-loader/lib/plugin

webpack.config

var path = require('path');
var webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
    entry: ['babel-polyfill','./src/main.js'], //项目入口文件
    output: {
        path: path.resolve(__dirname, './dist'), //项目打包后的文件路径
        publicPath: '/dist/', // 通过devServer访问路径,见下方devServer
        filename: 'custom.js' // 打包后的文件名,可自定义名称
    },
    plugins: [
        new VueLoaderPlugin()
    ],
    devServer: {
        historyApiFallback: true,
        overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader'
                ],
            },
            {
                test: /\.sass$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader?indentedSyntax'
                ],
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]?[hash]'
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        'scss': [
                            'vue-style-loader',
                            'css-loader',
                            'sass-loader'
                        ],
                        'sass': [
                            'vue-style-loader',
                            'css-loader',
                            'sass-loader?indentedSyntax'
                        ]
                    }
                }
            }
        ]
    }
};

第三行我新增了

const VueLoaderPlugin = require('vue-loader/lib/plugin');

在出口 output 下面新增了 

plugins: [
    new VueLoaderPlugin()
],

再次启动项目,OK啦,完美运行

6、调试

当我们开发项目调试中,例如 console.log ,刚好我们在上面也有一个

 console.log(...[1, 2, 3])

在浏览器控制台打开你会发现是这样的

这是打包编译后的文件,我们没法知道是具体的哪一个文件,所以我们需要在 webpack.config 新增一行

module.exports = {
    entry: ['babel-polyfill', './src/main.js'],
    // 省略其他...

    devtool: '#eval-source-map'
};

这样重启后再回到控制台查看打印内容就是以下这样的

这样就能清楚地看出来是在 App.vue 文件下打印的

7、编译打包

还在研究中......

参考文章:https://segmentfault.com/a/1190000012789253#articleHeader3

我就是参照以上衔接自己配置了一个项目,请允许我不要脸的添加上原创的标签

我和他的不同在于,他的 webpack 基于 3.10.0,我的 webpack 基于4.30.0,其中的配置就有所改变,我已经做了处理,比如

第 3 点和第 5 点,这里要特别注意

OK,完啦,一个简单的vue开发环境搭建成功,打包编译研究完成后会续上的

猜你喜欢

转载自blog.csdn.net/guozhangqiang/article/details/89497827