webpack搭建VUE项目 ----- 更好的配置webpack

在之前的文章中,我们用简单的webpack来搭建了一个react项目,但我们可以很明显的发现仅仅是那样是不够开发用的,今天我将我在开发中的webpack配置分享,并解析其中的含义,之后我会把代码上传到我的GitHub上,欢迎大家下载。

开始搭建一个vue项目。

按照惯例,先介绍一下按照我的步骤完成后出现的文件结构。

 

一、依然是在vue-cli目录下的命令行输入 npm init -y 生成package.json。

 

二、创建webpack.base.js 和 webpack.dev.js 

这里解释一下为什么不用webpack.config.js 而分成这两个:

1、base文件可以复用。

2、更清楚的文件结构。

后面会简称它们为 base.js,dev.js。

 

三、安装相关配置项

命令行输入:

 

npm i webpack wepack-cli webpack-dev-server vue-loader vue-template-compiler style-loader css-loader portfinder url-loader webpack-merge html-webpack-plugin -D

这里贴上所使用的包的版本号
    "css-loader": "^4.2.2",
    "html-webpack-plugin": "^4.3.0",
    "portfinder": "^1.0.28",
    "style-loader": "^1.2.1",
    "url-loader": "^4.1.0",
    "vue-loader": "^15.9.3",
    "vue-template-compiler": "^2.6.12",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0",
    "webpack-merge": "^5.1.2"

 

 

 

我会在配置中遇到时解释它们。

 

四、配置base.js

首先,我们来看一下base.js的文件结构

const { join } = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const VueLoaderPlugin = require("vue-loader/lib/plugin");

const APP_PATH = join(__dirname, "src");
const BUILD_PATH = join(__dirname, "dist");

module.exports = {
  entry: {},
  output: {},
  module: {},
  resolve: {},
  plugins: [],
};

 

如果看过我前面的文章的话,module.exports里的内容就不需要解释了,主要解释一下上面的那些

第一句:引用path里的join方法。

第二句:使用html-webpack-plugin,它的功能是简化了HTML文件的创建,以便为你的webpack包提供服务。

第三句: 使用vue-loader里的插件,这样在我们配置解析.vue的规则是才能使用vue-loader。

后面这两句是将src的路径和dist的路径赋予给这两个量。

这里的__dirname指是当前文件,也就是base.js文件的绝对路径。

首先,我们的entry里的代码:

entry: {
    index: join(__dirname, "src/index.js"),
  },

 

配置入口文件,不解释。

 

output:

output: {
    path: BUILD_PATH,
    filename: "bundle.js",
  },

 

配置出口文件,不解释。

 

module:

module: {
    rules: [
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: ["vue-loader"],
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: ["style-loader","css-loader"]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
    ],
  },

 

第一个rule:解析.vue文件。

第二个rule:解析.css文件。

第三个rule:解析图片文件。

第四个rule:解析视频文件。

第五个rule:解析字体文件。

 

resolve:

resolve: {
    modules: ["node_modules"],
    extensions: ["less", ".js", ".vue"],
    alias: {
      "@": APP_PATH, // 为该路径配置别名。在项目中可以使用该别名代替该路径
    },
  },

 

配置文件名和路径名的别名和省略。

modules:引入模块可以简写。

extensions:省略扩展名的文件的扩展名查询,从后到前。

alias:路径的别名命名。

 

plugins:

plugins: [
    new htmlWebpackPlugin({
      template: "./index.html",
    }),
    new VueLoaderPlugin(),
 ],

 

第一个插件:配置静态HTML文件目录和一些HTML的配置项。

第二个插件:使vue-loader能够使用。

完整代码:

const { join } = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const VueLoaderPlugin = require("vue-loader/lib/plugin");

const APP_PATH = join(__dirname, "src"); // 把路径赋予,方便使用
const BUILD_PATH = join(__dirname, "dist");

module.exports = {
  entry: {
    index: join(__dirname, "src/index.js"),
  },
  output: {
    path: BUILD_PATH,
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: ["vue-loader"],
      },
      {
        test: /\.css$/, //处理css
        exclude: /node_modules/,
        use: [ "style-loader", "css-loader"],
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
    ],
  },
  resolve: {
    modules: ["node_modules"],
    extensions: ["less", ".js", ".vue"],
    alias: {
      "@": APP_PATH, // 为该路径配置别名。在项目中可以使用该别名代替该路径
    },
  },
  plugins: [
    new htmlWebpackPlugin({
      template: "./index.html",
    }),
    new VueLoaderPlugin(),
  ],
};

 

 

五、配置dev.js

 文件代码:

const webpack = require("webpack");
const { merge } = require("webpack-merge");
const portFinder = require('portfinder'); // 当端口被占用时,会让端口数+1,保证正常运行

const webpackNaseConfig=require('./webpack.base');
const webpackDevConfig =merge(webpackNaseConfig,{
    mode:'development',
    devtool:'#cheap-module-eval-source-map', // 改变调试过程和速度
    context:__dirname, // 上下文 用于从配置中解析入口起点(entry point)和 loade
    devServer:{
        compress:true, // 是否启用gzip压缩文件
        historyApiFallback:true, // 当找不到页面(404)时返回到首页
        host:'localhost',
        hot:true,
        open:true,
        quiet:true, // 将编译时候的信息只在第一次输出
        overlay:{ // 浏览器中显示错误
            warnings:true,
            errors:true,
        },
    },
    watchOptions:{ // 监听
        ignored:[ // 不被监听项
            /node_modules/,
        ],
    },
    plugins:[
        new webpack.HotModuleReplacementPlugin(),
    ],
});

module.exports=portFinder.getPortPromise({
    port:8080,
}).then((port)=>merge(webpackDevConfig,{
    devServer:{
        port,
    },
}))

介绍几个没有说过的:

webpack-merge:将webpack配置项合并

portfinder:当端口被占用时,会让端口数+1,保证正常运行。

devtool:改变调试过程和速度。

context:上下文 用于从配置中解析入口起点(entry point)和 loade。

compress:是否启用gzip压缩文件。

historyApiFallback:当找不到页面(404)时返回到首页。

quiet: 将编译时候的信息只在第一次输出。

overlay: 浏览器中显示错误。

watchOptions:监听。

ignored:不被监听项。

最后的部分是portfinder的配置,意思是挂在8080端口,同时配置devServer的port项。

 

六、配置index.html

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="../dis/bundle.js"></script>
</body>
</html>

 

 

 

 

跟之前的文章意义一样。

 

七、配置src下的index.js

首先先安装包:

npm i vue vue-router -S

 

代码:

import Vue from "vue";
import App from "@/App.vue";
import router from "@/router/index.js";

new Vue({
  el: "#app",
  router,
  render: (h) => h(App), //vue在创建Vue实例时,通过调用render方法来渲染实例的DOM树,也就是这个组件渲染的是App的内容
  //vue在调用render方法时,会传入一个createElement函数作为参数,也就是这里的h的实参是createElement函数,然后createElement会以App为参数进行调用
})

 

vue的东西,不在这里解释了。

 

八、配置App.vue

代码:

<template>
    <div id="app">
        hello world
        <router-view />
    </div>
    
</template>
<script>
export default {
    name:'app'
}
</script>
<style scoped>

</style>

 

 

九、配置router的index.js

代码:

import Vue from "vue";
import vueRouter from "vue-router";
import hellow from "@/components/hellow.vue";
Vue.use(vueRouter);

export default new vueRouter({
  routes: [
    {
      path: "/",
      component: hellow,
    },
  ],
});

 

vue的,不解释。

 

十、components的hellow

代码:

<template>
    <div id="hellow">
        HELLO WORLD
    </div>
</template>
<script>
export default {
    name:'hellow'
}
</script>

 

 

十一、package.json

代码(主要改这里):

"scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js --progress --colors"
  },

 

 

至此,vue项目配置完成,为了使项目配置更加的合理化,便利化。引入一些插件

 

一、mini-css-extract-plugin

功能: 将CSS提取为独立的文件的插件,对每个包含css的js文件都会创建一个CSS文件

安装:

 npm i mini-css-extract-plugin -D

 

使用:配置base.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 头部引入

{                      // 修改rules中 CSS配置
  test: /\.css$/, //处理css
  exclude: /node_modules/,
  use: [
    {
      loader : process.env.NODE_ENV === "production"? MiniCssExtractPlugin: "style-loader",
    },
    {
      loader: "css-loader",
    },
  ],
},

 

 

二、copy-webpack-plugin

功能:主要用于拷贝文件,常用来将静态文件(图片等)从开发环境拷贝到生产环境。

安装:

npm i copy-webpack-plugin -D

 

配置:base.js

const CopyWebpackPlugin = require("copy-webpack-plugin"); // 引入

// plugins 里的配置
new CopyWebpackPlugin({ patterns: [ { from: `${APP_PATH}/assets/`, to: `${BUILD_PATH}/assets/`, }, ], }),

 

 

三、friendly-errors-webpack-plugin

功能:友好的错误提示插件。

安装:

 npm i friendly-errors-webpack-plugin -D

 

配置:dev.js

const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); // 引入

// plugins 里配置
new FriendlyErrorsPlugin(),

 

 

最后的base.js 代码

const { join } = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 将CSS提取为独立的文件的插件,对每个包含css的js文件都会创建一个CSS文件
const CopyWebpackPlugin = require("copy-webpack-plugin"); // 将一个文件拷贝到另一个文件
const VueLoaderPlugin = require("vue-loader/lib/plugin");

const APP_PATH = join(__dirname, "src"); // 把路径赋予,方便使用
const BUILD_PATH = join(__dirname, "dist");

module.exports = {
  entry: {
    index: join(__dirname, "src/index.js"),
  },
  output: {
    path: BUILD_PATH,
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: ["vue-loader"],
      },
      {
        test: /\.css$/, //处理css
        exclude: /node_modules/,
        use: [
          {
            loader:
              process.env.NODE_ENV === "production"
                ? MiniCssExtractPlugin
                : "style-loader",
          },
          {
            loader: "css-loader",
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        use: ['url-loader'],
        include: [
          APP_PATH,
        ],
      },
    ],
  },
  resolve: {
    modules: ["node_modules"],
    extensions: ["less", ".js", ".vue"],
    alias: {
      "@": APP_PATH, // 为该路径配置别名。在项目中可以使用该别名代替该路径
    },
  },
  plugins: [
    new htmlWebpackPlugin({
      template: "./index.html",
    }),
    new VueLoaderPlugin(),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: `${APP_PATH}/assets/`,
          to: `${BUILD_PATH}/assets/`,
        },
      ],
    }),
  ],
};

 

dev.js代码

const webpack = require("webpack");
const { merge } = require("webpack-merge");
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); // 友好的错误提示
const portFinder = require('portfinder'); // 当端口被占用时,会让端口数+1,保证正常运行

const webpackNaseConfig=require('./webpack.base');
const webpackDevConfig =merge(webpackNaseConfig,{
    mode:'development',
    devtool:'#cheap-module-eval-source-map', // 改变调试过程和速度
    context:__dirname, // 上下文 用于从配置中解析入口起点(entry point)和 loade
    devServer:{
        compress:true, // 是否启用gzip压缩,压缩文件
        historyApiFallback:true, // 当找不到页面时返回到首页
        host:'localhost',
        hot:true,
        open:true,
        quiet:true, // 将编译时候的信息只在第一次输出
        overlay:{ // 浏览器中显示错误
            warnings:true,
            errors:true,
        },
    },
    watchOptions:{ // 监听
        ignored:[ // 不被监听项
            /node_modules/,
        ],
    },
    plugins:[
        new FriendlyErrorsPlugin(),
        new webpack.HotModuleReplacementPlugin(),
    ],
});

module.exports=portFinder.getPortPromise({
    port:8080,
}).then((port)=>merge(webpackDevConfig,{
    devServer:{
        port,
    },
}))

 

 

至此,配置完成,如果哪里有问题,欢迎评论区提问和指正。

 

posted @ 2020-08-26 11:32  FuloliyaLansfroya  阅读(207)  评论(0)    收藏  举报