使用webpack4搭建一个vue开发环境(1)

137 阅读1分钟

webpack.common.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const VueLoaderPlugin = require("vue-loader/lib/plugin");
​
module.exports = {
    entry: {
        mainPage: path.resolve(__dirname, "../src/main.js")         // 指定入口文件,也可以设置多入口
    },
    output: {
        path: path.resolve(__dirname, "../dist"),                   // 打包输出路径
        filename: "js/[name].js",                                   // 输出文件名
    },
    module: {
        rules: [
            {
                test: /.(png|jpg|gif)$/i,                          // 使用url-loader处理图片,配合file-loader使用,100kb以下图片会被处理成base64,超过100kb会被file-loader处理
                use: [{
                    loader: "url-loader",
                    options: {
                        limit: 100,
                        outputPath: "images",
                        name: "[name].[ext]?v=[hash:8]"
                    }
                }]
            },
            {
                test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/,  // 处理音视频文件
                use: [{
                    loader: "url-loader",
                    options: {
                        limit: 100,
                        outputPath: "media",
                        name: "[name].[ext]?v=[hash:8]"
                    }
                }]
            },
            {
                test: /.(woff2?|eot|ttf|otf)(?.*)?$/i,            // 处理字体文件
                use: [{
                    loader: "url-loader",
                    options: {
                        limit: 100,
                        outputPath: "fonts",
                        name: "[name].[ext]?v=[hash:8]"
                    }
                }]
            },
            {
                test: /.(js|jsx)$/,                                // 使用babel处理js、jsx,可以将es6等高级语法转变成低级语法
                use: [{
                    loader: "babel-loader",
                    options: {
                        presets: ["@babel/preset-env"]
                    }
                }],
                exclude: /node_modules/,
            },
            {                                                       // 使用vue-loader处理vue文件,需要配合vue-template-compiler使用
                test: /.vue$/,
                use: ["vue-loader"],
                exclude: /node_modules/,
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({                                     // 指定html模板文件,可以通过实例化多个HtmlWebpackPlugin()来指定多个html模板
            template: path.resolve(__dirname, '../src/index.html'),
            filename: "index.html",
            minify: false,
            hash: true,
        }),
        new VueLoaderPlugin(),                                      // 使用.vue文件
    ]
}

webpack.dev.js

const path = require("path");
const { merge } = require("webpack-merge");
const common = require("./webpack.common");
const webpack = require("webpack");
​
module.exports = merge(common, {
    mode: "development",                        // 开发环境
    devServer: {
        port: 1100,                             // 端口号
        open: true,                             // 自动打开浏览器
        hot: true,                              // 热更新
        proxy: {                                // 可以设置代理
            "/api": {
                target: "https://kt.fkw.com",
                changeOrigin: true,
                pathRewrite: {
                    "^/api": ""
                }
            }
        }
    },
    stats: 'errors-only',                       // 只输出错误
    devtool: "source-map",                      // css、js都会默认开启sourceMap
    module: {
        rules: [
            {                                   // 使用postcss-loader和autoprefixer自动添加浏览器前缀,用css-loader、style-loader处理样式
                test: /.css$/,
                use: [{
                    loader: "style-loader"
                }, {
                    loader: "css-loader",
                }, {
                    loader: "postcss-loader",
                }],
                exclude: /node_modules/,
            },
            {
                test: /.(sass|scss)$/,         // 使用sass-loader和node-sass处理sass
                use: [{
                    loader: "style-loader"
                }, {
                    loader: "css-loader",
                }, {
                    loader: "postcss-loader",
                }, {
                    loader: "sass-loader",
                }],
                exclude: /node_modules/,
            },
        ]
    },
    plugins: [
        new webpack.DefinePlugin({              // 定义全局变量,区分开发环境和生产环境
            __dev__: true,
        }),
        new webpack.HotModuleReplacementPlugin(),   // 热更新
    ]
})

webpack.build.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { merge } = require("webpack-merge");
const common = require("./webpack.common");
​
module.exports = merge(common, {
    mode: "production",             // 生产环境
    devtool: "source-map",          // css、js都会默认开启sourceMap
    module: {
        rules: [
            {
                test: /.css$/,
                use: [{
                    loader: MiniCssExtractPlugin.loader,    // 抽离出css文件,使用mini-css-extract-plugin可能会导致sourceMap失效
                    options: {
                        publicPath: "../",                  // 解决图片等资源路径错误的问题
                    }
                }, {
                    loader: "css-loader",
                }, {
                    loader: "postcss-loader",
                }],
                exclude: /node_modules/,
            },
            {
                test: /.(sass|scss)$/,
                use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: "../",
                    }
                }, {
                    loader: "css-loader",
                }, {
                    loader: "sass-loader",
                }, {
                    loader: "postcss-loader",
                }],
                exclude: /node_modules/,
            },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'style/[name].[hash:8].css',                  // 抽离css文件到style文件夹下
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../src/index.html'),
            filename: "index.html",
            minify: true,
            hash: true,
        }),
    ]
})

vue、vue-router、vueX

npm i vue vue-router vueX下载3个包。

配置路由

import VueRouter from "vue-router";
import Vue from "vue";
​
Vue.use(VueRouter);
​
const routes = [
    {
        path: "/",
        redirect: "home",
    }, {
        path: "/home",
        component: () => import("../page/Home.vue"),
        name: "home",
    }
]
​
export default new VueRouter({
    history: "hash",
    routes,
})

配置vueX

import Vuex from "vuex";
import Vue from "vue";
import data from "./modules/data.js";
import index from "./modules/index";
​
Vue.use(Vuex);
const store = {
    state: {
        hhh: 1,
    },
    mustation: {
​
    },
    action: {
​
    },
    getter: {
​
    },
    modules: {
        data,
        index,
    }
};
​
export default new Vuex.Store(store);

使用vue

import Vue from "vue";
import App from "./view/App.vue";
import store from "./store/store.js";
import router from "./router/route.js";
​
const vm = new Vue({
    el: "#app",
    store,
    router,
    render: h => h(App)
});
// App.vue
​
<template>
    <div>
        vue app
        <div class="ul">
            <li>1</li>
        </div>
        <router-view></router-view>
    </div>
</template><script>
export default {
    created(){
        console.log("created");
        console.log(this.$store.state);
    }
}
</script><style lang="scss">
.ul {
    li {
        background-color: rgb(201, 73, 73);
    }
}
</style>

package.json

所有不说明依赖包版本的webpack配置都是在耍流氓,谁知道下一个版本的语法怎么变化呢。

{
    "name": "project4",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "dev": "webpack serve --config ./build/webpack.dev.js",
        "build": "webpack --config ./build/webpack.build.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@babel/core": "^7.2.0",
        "@babel/preset-env": "^7.2.0",
        "autoprefixer": "^8.0.0",
        "babel-loader": "^8.1.0",
        "css-loader": "^4.1.0",
        "file-loader": "^5.0.1",
        "html-webpack-plugin": "^4.4.1",
        "mini-css-extract-plugin": "^0.12.0",
        "node-sass": "^4.13.0",
        "postcss-loader": "^4.0.1",
        "sass-loader": "^8.0.1",
        "style-loader": "^1.2.1",
        "url-loader": "^3.0.0",
        "vue-loader": "^15.0.0",
        "vue-template-compiler": "^2.6.14",
        "webpack": "^4.46.0",
        "webpack-cli": "^4.9.2",
        "webpack-dev-server": "^3.11.3",
        "webpack-merge": "^5.8.0"
    },
    "dependencies": {
        "vue": "^2.6.14",
        "vue-router": "^3.5.3",
        "vuex": "^3.6.2"
    },
    "browserslist": [
        "defaults",
        "not ie <= 8",
        "last 2 versions",
        "> 1%",
        "iOS >= 7",
        "Android >= 4.0"
    ]
}

打包效果

image.png

最后

这只是一个简单的webpack配置,还有很多地方值得去优化,留着下次一定优化。