基于Webpack4的Vue移动端开发环境-搭建篇

写在前面

在使用Vue开发单页面的时候,咱们大多数时候都是使用的官方CLI工具,如今的Vue CLI已经迭代到了4.X了,能够说很成熟稳定了,能知足大多数要求,并且上手简单。本着折腾摸索的精神,仍是打算本身搭建一个开发环境,熟悉各个流程。css

本文不涉及Webpack和babel知识的讲解,建议了解一下Webpack的基本知识来看这篇文章会更好理解。这个在网上能找到不少教程。关于node.js和npm安装在这里也再也不赘述,相信作前端开发这个是电脑必备的。html

若是你在搭建过程当中遇到不明的报错,查看报错信息并记录排查,有时候相关的插件在更新事后使用方式会发生变化,有可能你按着个人配置走下来也报错,那么看看官方文档(通常在github上查相关的仓库便可)有没有改变写法,好比此次我配置的clean-webpack-plugin插件,之前的版本是不须要解构的,可是如今必须解构了,否则它会报错并提示不是构造函数前端

大佬绕路轻喷。。。vue

更新:若是开发环境和生产环境都使用插件把CSS分离出来成为单独的文件,那么你在开发过程当中会发现热更新对CSS不生效,因此解决方法就是分离CSS仅配置在生产环境。给你们埋了个坑,sorry!node

优化篇已经出炉:基于Webpack4的Vue移动端开发环境-优化篇webpack

个人node.js及npm版本以下:css3

node -v
v12.13.0

npm -v
v6.12.0
复制代码

开始

一、初始化一个项目

首先你要新建一个文件夹,我这儿叫 customized-vue-proj-mobile,而后在你的文件夹右键打开git bash输入如下命令来初始化项目(须要安装git,固然用cmd也是能够的):git

npm init
复制代码

执行完这个命令事后,会在目录生成一个 package.json 的文件,个人文件内容以下:es6

{
  "name": "customized-vue-proj-mobile",
  "version": "1.0.0",
  "description": "customized vue development environment",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/cookiepool/customized-vue-proj-mobile.git"
  },
  "keywords": [
    "vue",
    "mobile"
  ],
  "author": "LEE",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/cookiepool/customized-vue-proj-mobile/issues"
  },
  "homepage": "https://github.com/cookiepool/customized-vue-proj-mobile#readme"
}
复制代码

这儿关于npm包管理也有不少知识点,这里不在展开,建议你们能够自行了解下github

这样一个项目就先初始化完毕,接下来开始进入各类工具的安装来完成环境的搭建。

二、安装webpack

基于webpack的话确定要先安装好webpack才能继续安装后续的,因此先来安装命令:

npm install webpack --save-dev
复制代码
  • --save-dev 表示将包安装信息放入到 package.jsondevDependencies 里面,这个不会用于生产环境,-D 等效于 --save-dev
  • --save 表示将包安装信息放入到 package.jsondependencies 里面,这个会打包用于生产环境。-S 等效于 --save

接下来还须要安装CLI,从webpack4开始必需要安装webpack cli才能执行webpack相关的命令

npm install webpack-cli -D
复制代码

接下来输入 npx webpack --help 来测试webpack是否处于可用状态,若是输入这个命令后面板出现一大串配置帮助信息则表明webpack可用。

npx 能够直接调用项目内部安装的模块,而不须要全局安装npm模块,若是上面的命令你不使用npx你会发现系统显示 bash: webpack: command not found


如今在项目目录下新建一个src文件夹,里面新建一个main.js文件,在里面先随便写点js代码。而后在创建一个build文件夹,并新建一个webpack.config.js配置文件。这样一来咱们的目录结构就是这个样子:

1.png

文件建好了可是尚未内容,确定跑不起来,接下来对webpack.config.js操做一番,这里我不叙述具体过程了(#滑稽保命),直接贴代码,里面我写了注释:

// build/webpack.config.js
// node.js里面自带的操做路径的模块
const path = require('path');

module.exports = {
  // 指定模式,这儿有none production development三个参数可选
  // 具体做用请查阅官方文档
  mode: 'development',
  // webpack打包的入口文件
  entry: {
    main: path.resolve(__dirname, '../src/main.js')
  },
  // webpack打包的输出相关的额配置
  output: {
    // 打包事后的文件的输出的路径
    path: path.resolve(__dirname, '../dist'),
    // 打包后生成的js文件,带hash值来保证文件的惟一性
    filename: 'js/[name].[hash:4].js',
    // 生成的chunk文件名
    chunkFilename: 'js/[name].[hash:4].js',
    // 资源的引用路径(这个跟你打包上线的配置有关系)
    publicPath: '/'
  }
}
复制代码

而后呢再把package.json改造一下,在scripts处添加一句 dev 这个命令:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack ./src/main.js --config ./build/webpack.config.js"
},
复制代码

一顿操做事后,咱们开始来试一试这个命令能不能用,在控制台下输入:

npm run dev
复制代码

稍等一下子就会出现如下信息,则表明咱们打包输出成功:

2.png

此时项目的结构变成这个样子:

3.png

环境搭建到这儿只能说webpack配置正常了,还有许多额外东西须要配置,好比如下

  • babel,这个能够把ES6+转换为低浏览器可用的ES5,以及对一些新API作polyfill处理
  • css预处理器,目前css预处理器有不少选择,这里我选择了scss来作配置,固然你不使用css预处理器也是能够的。
  • 文件处理loader,这个主要是项目相关的图片、字体、音视频的处理。
  • html文件自动建立,你打包好的js文件等须要正确的导入html才能正常使用。
  • postcss,这个工具主要是处理css的,安装相关的插件能够实现一些功能,好比自动添加css3的前缀,移动开发中用到的px-to-rem或者px-to-vw等等。
  • 热更新功能,在开发过程当中自动响应咱们的修改并更新,不须要手动刷新。
  • 识别.vue文件,这个是让webpack识别.vue文件并转换成浏览器能使用的内容。
  • 集成vue-router和vuex,作单页面路由不可少,状态管理根据须要来引入便可,不是必需要配置的东西。

三、配置相关工具

3.一、ES6+转ES5

首先来一波安装命令,安装好相关的依赖:

npm install babel-loader @babel-core @babel/preset-env -D
复制代码
  • bable-loader 这个是用于webpack来处理babel的加载器,用于调用@babel/core的核心API来完成编译。
  • @babel-core babel的核心,核心的api都在包含在这里。
  • @babel/preset-env babel的一个预置环境。

参考我这篇文章来了解一下babel,固然社区上还有许多大佬写的文章,多看几篇能够了解的更加透彻。

  • 修改webpack.config.js

如今咱们须要配置webpack来使其支持babel,这里就须要使用到刚才安装的babel-loader。在配置文件中加入如下代码:

module: {
  rules: [
    {
      test: /\.jsx?$/,
      exclude: /node_modules/,
      use: [
        {
          loader: 'babel-loader'
        }	
      ]
    }
  ]
}
复制代码
  • 在项目的根目录新建babel.config.js

在文件中加入如下内容:

// babel.config.js
module.exports = {
  // 配置预置环境
  presets: [
    // 使用的规则
    "@babel/preset-env"
  ]
}
复制代码

配置好后,去main.js里面写一些es6+的语法的js代码,而后执行 npm run dev 你会发现dist目录下生成的js文件语法都转换成es5的了,可是promise却没有转换,这里咱们还须要polyfill。

  • 配置polyfill而且按需引入

输入如下命令安装必须的依赖:

npm install core-js@2 -S
复制代码

安装完毕后去babel.config.js修改代码以下:

module.exports = {
  // 配置预置环境
  presets: [
    // 使用的规则
    ["@babel/preset-env", {
      // 这儿有false, entry, usage三个可选参数,usage能够按需引入polyfill
      "useBuiltIns": "usage",
      // 指定corejs版本
      "corejs": 2
    }]
  ]
}
复制代码

这样一来你的js就能够运行在低版本浏览器里面了,好比Promise。

3.二、配置css预处理器

仍是先安装依赖

npm install sass-loader dart-sass css-loader style-loader -D
复制代码
  • style-loader 该loader主要是把css解析到html的style标签上。
  • css-loader 该loader用来解析css,注意在调用style-loader和css-loader时,css-loader要先于style-loader执行,否则会报错,当你使用如下写法时:
use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
复制代码

由于loader加载是从右往左加载。(为何从右往左加载 )这里的编译顺序是先用css-loader将css代码编译,再交给style-loader插入到网页里面去。因此css-loader在右,style-loader在左。

  • sass-loader 该loader把scss或sass转换为css。
  • dart-sass 这个工具相似于编译器,转换scss语法,结合到sass-loader使用,其实还有个node-sass可使用。使用node-sass的话能够不用在webpack的配置文件里面指定,只须要用npm安装好node-sass便可,这儿我使用了dart-sass因此要在implementation中指定。

下载安装好依赖事后,在配置文件 webpack.config.js 中的 module->rules 里面加入如下代码:

{
  test: /\.(scss|sass)$/,
  use: [
    {
      loader: 'style-loader',
    },
    {
      loader: 'css-loader',
    },
    {
      loader: 'sass-loader',
      options: {
        implementation: require('dart-sass')
      }
    }
  ]
}
复制代码

3.三、建立Html文件以及相关处理

首先在项目目录建立一个目录public,里面再建立一个index.html,做为单页面的惟一入口。代码以下:

<!DOCTYPE html>
<html lang="en">
<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>customized-vue-proj-mobile</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>
复制代码

此时目录结构变成如图所示

4.png

建立好文件后咱们须要一个插件来处理html文件,只有js文件正常导入到html文件咱们的项目才能运行起来,输入如下命令来安装 html-webpack-plugin

npm install html-webpack-plugin -D
复制代码

安装完成后,再webpack配置文件的plugins中加入如下代码:

plugins: [
  new htmlWebpackPlugin({
    // 指定模板
    template: path.resolve(__dirname, '../public/index.html'),
    // 输出的文件
    filename: path.resolve(__dirname, '../dist/index.html')
  })
]
复制代码

3.四、配置字体、图片等文件的处理

开发过程确定会遇到不少媒体文件,特别是图片,webapck有专门的loader来处理这些文件,先安装好依赖:

npm install url-loader file-loader -D
复制代码
  • url-loader和file-loader,这两个其实功能差很少,url-loader的好处就是当文件小于咱们指定的大小时,它能够把媒体文件转换成base64编码,这样能够减小项目的图片请求,提升访问速度。

而后咱们在webpack的配置文件中加入如下代码:

{
  test: /\.(jpe?g|png|gif)$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        // 当文件大于5kb时走file-loader相关的配置
        limit: 5120,
        // 这个参数要设置成false,否则生成图片的路径时[object Module]
        esModule: false,
        // 当文件大于5kb时走file-loader相关的配置
        fallback: 'file-loader',
        // 生成的路径和文件名
        name: 'images/[name].[hash:4].[ext]'
      }
    }
  ]
},
{
  test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 5120,
        esModule: false,
        fallback: 'file-loader',
        name: 'media/[name].[hash:4].[ext]'
      }
    }
  ]
},
{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 5120,
        esModule: false,
        fallback: 'file-loader',
        name: 'fonts/[name].[hash:4].[ext]'
      }
    }
  ]
},
复制代码

以上咱们就配置好了媒体文件相关的处理。

3.五、让webpack识别vue文件

安装依赖:

npm install vue-loader vue-template-compiler -D
复制代码
  • vue-loader必须结合vue-template-compiler来使用,不然是不能完成转换的。

首先配置module里面的内容:

{
  test: /\.vue$/,
  use: [
    {
      loader: 'vue-loader',
      options: {
        compilerOptions: {
          preserveWhitespace: false
        }
      }
    }
  ]
}
复制代码

配置里面有个compilerOptions的参数preserveWhitespace为false,这个意思是当它的值为true时意味着编译好的渲染函数会保留全部 HTML 标签之间的空格。若是设置为 false,则标签之间的空格会被忽略。这可以略微提高一点性能可是可能会影响到内联元素的布局。具体参考此处:连接

配置好module后咱们还要引入插件,这个是必须的

// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin');

// 添加到plugins中
new VueLoaderPlugin()
复制代码

具体的你们能够参考此处:连接

而后咱们还须要配置alias,这样能够减小路径过长引用的麻烦:

resolve: {
  alias: {
    // 写了这句,咱们能够这样写代码 import Vue from 'vue', 而且引入的是vue/dist/vue.runtime.esm.js这个版本,否则默认引入的是vue.js。这个在github的vue官方仓库dist目录下有解释。
    'vue$': 'vue/dist/vue.runtime.esm.js',
    // 写了这句,咱们能够这样写代码 import api from '@/api/api.js',省去处处找路径定位到src的麻烦
    '@': path.resolve(__dirname, '../src')
  },
  // 添加一个 resolve.extensions 属性,方便咱们引入依赖或者文件的时候能够省略后缀
  // 咱们在引入文件时能够这样写 import api from '@/api/api'。
  extensions: ['*', '.js', '.vue']
},
复制代码

3.六、配置postcss

这个地方我配置了三个插件,autoprefixer、postcss-pxtorem、postcss-px-to-viewport,后两个你只须要配置其中一个便可,主要看你开发使用的rem仍是vw,自行选择便可。

npm install postcss-loader autoprefixer postcss-pxtorem postcss-px-to-viewport -D
复制代码
  • postcss-loader 负责postcss相关的操做。
  • autoprefixer 为浏览器添加不一样的css3前缀。
  • postcss-pxtorem px自动转换为rem。
  • postcss-px-to-viewport px自动转换为vw|vh。

安装好依赖事后,在项目的根目录创建文件 postcss.config.js,而后在文件中输入如下内容:

module.exports = {
    plugins: {
        // 这个工具能够实现自动添加CSS3前缀
        "autoprefixer": {},
        // 若是你使用rem来实现移动端多设备适配,这个工具能够把px转换为rem
        /* "postcss-pxtorem": {
        	rootValue: 37.5, // 指定转换倍率,我如今设置这个表示1rem=37.5px;
        	propList: ['*'], // 属性列表,表示你要把哪些css属性的px转换成rem,这个*表示全部
        	minPixelValue: 1, // 须要转换的最小值,通常1px像素不转换,以上才转换
        	unitPrecision: 6, // 转换成rem单位的小数点后的保留位数
        	selectorBalckList: ['van'], // 匹配不被转换为rem的选择器
        	replace: true, // 替换包含rem的规则,而不是添加回退
        	mediaQuery: false // 容许在媒体查询中转换px
        }, */
        // 若是你使用vw来实现移动端多设备适配,这个工具能够把px转换为vw
        "postcss-px-to-viewport": {
        	unitToConvert: 'px', // 把什么单位转换成vw
        	viewportWidth: 750, // 这个能够按照你的设计稿来设置,是750就设置750,375就设置成375
        	unitPrecision: 6, // 转换成vw单位的小数点后的保留位数
        	propList: ['*'], // 属性列表,表示你要把哪些css属性的px转换成vw,这个*表示全部
        	viewportUnit: 'vw', // 使用的单位,目前可选单位有vw,vh。通常咱们都有vw
        	fontViewportUnit: 'vw', // 字体使用的单位
        	selectorBlackList: [], // 匹配不被转换为vw的选择器
        	minPixelValue: 1, // 须要转换的最小值,通常1px像素不转换,以上才转换
        	mediaQuery: false, // 容许在媒体查询中转换px
        	replace: true, // 替换包含vw的规则,而不是添加回退
        	exclude: [], // 忽略一些文件,好比“node_modules”,能够是正则表达式
        	landscape: false,  // ......
        	landscapeUnit: 'vw', // ......
        	landscapeWidth: 568 // ......
        }
    }
}
复制代码

而后呢,webpack配置加上:

{
  test: /\.(scss|sass)$/,
  use: [
    {
      loader: 'style-loader',
    },
    {
      loader: 'css-loader',
    },
    {
      loader: 'sass-loader',
      options: {
        implementation: require('dart-sass')
      }
    },
    {
      loader: 'postcss-loader'
    }
  ]
}
复制代码

3.七、配置热更新功能

安装依赖:

npm install webpack-dev-server -D
复制代码

安装完成后,进行以下的配置:

// 引入webpack
const webpack = require('webpack');

// 配置devServer
devServer: {
  // 默认状况不设置这个只能经过localhost:9000来访问,如今能够经过本机局域网ip来访问,
  // 好比192.168.12.21:9000,手机在这个局网内也能够访问
  host: '0.0.0.0',
  hot: true,
  port: 9200,
  contentBase: './dist'
}

// 配置plugins
new webpack.NamedModulesPlugin(), // 辅助HotModuleReplacementPlugin插件
new webpack.HotModuleReplacementPlugin(), // 启用热更新必须的
复制代码

四、定义环境变量

这个主要是定义这个玩意儿 process.env.NODE_ENV ,定义好这个咱们通常能够来判断什么样的环境执行什么样的代码,咱们知道webpack的打包环境和开发环境配置通常是不同的,这里不展开,后面会讲。好比咱们在入口main.js里面这样来写代码判断:

if(process.env.NODE_ENV === 'development'){ 
  //开发环境 do something
}else if(process.env.NODE_ENV === 'production') {
  //生产环境 do something
}
复制代码

那么定义这个环境怎么操做呢,第一种是借助webpack的插件DefinePlugin,

  • 使用DefinePlugin 咱们在plugins里面加入如下代码:
new webpack.DefinePlugin({
  'process.env': {
    NODE_ENV: JSON.stringify('development')
  }
}),
复制代码

那么咱们最终打包事后访问到的process.env.NODE_ENV的值就是development。

另外一种使用webpack4本身集成了的环境判断,咱们只须要在配置文件里面声明mode便可,推荐使用这种

  • 使用webpack4的mode参数
module.exports = {
  // 有none production development三个参数可选,不设置mode的话默认的process.env.NODE_ENV值为production
  mode: "development",
  entry: {}
  .....
}
复制代码

有了上面的mode设置,咱们照样能取到process.env.NODE_ENV的值。 关于process.env.NODE_ENV的知识点这里有几篇文章能够参考:

连接-1 连接-2 连接-3

五、集成Vue全家桶

安装依赖

npm install vue vuex vue-router -S
复制代码

安装完依赖事后,在src目录下新建一个App.vue的文件。写入如下代码:

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
export default {
  
}
</script>

<style lang="scss">

</style>
复制代码

在src下再新建router、store两个目录,再目录下分别新建router.js和store.js。顺便再把其余文件夹也建好,如components、assets、views。如今个人目录结构以下图所示:

4.png

main.js里面修改成以下代码:

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

new Vue({
  router,
  render: h => h(App)
}).$mount("#app");
复制代码

建好这些文件事后其实后面的代码书写就跟官方脚手架搭建好的写法同样,这里就不在演示其它文件的代码怎么书写了,到时能够参考个人源代码。

这儿引入vue-router和vuex事后,根据官方文档作好配置便可开始测试,我这个只测试了vue和vue-router的功能正常,vuex暂时只创建了文件,但未进行实际引入测试。后面我会把源代码提交到github供你们参考

这个时候,咱们直接npm run dev的话会打包,因此咱们须要把package.json的scripts中的dev改为以下的代码:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack-dev-server --config ./build/webpack.config.js"
},
复制代码

走到这步,若是你作好了前面的工做,理论上这儿执行npm run dev后就能看到效果了,我这儿的效果如图所示:

6.gif

六、区分开发环境和生产环境

作单页面开发咱们都知道,开发环境和生产环境是不太同样的,平时使用官方cli时开发命令用的npm run dev,而打包发布时npm run build。这里面的配置确定是存在区别的。

如今在build目录下新建webpack.dev.js和webpack.prod.js两个文件,用来区分开发环境和生产环境。同时把开发环境和生产环境通用的配置都写在webpack.config.js里面。

  • 开发环境

一、webpack的mode属性值设置为development,开启这个不会压缩代码。
二、须要webpack-dev-server和热更新。
三、css不用提取到单独文件并压缩(固然你也能够提出来)
四、不须要构建前清除上一次构建内容
五、不须要打包分析

  • 生产环境

一、webpack的mode属性值设置为production,开启这个会压缩代码。
二、不须要webpack-dev-server和热更新。
三、css要提取到单独文件并压缩
四、须要构建前清除上一次构建内容
五、须要打包分析

好了,大概了解了区别后,咱们还须要单独安装其余没有的依赖,先来波安装命令,一把梭:

npm i clean-webpack-plugin copy-webpack-plugin @intervolga/optimize-cssnano-plugin mini-css-extract-plugin webpack-merge webpack-bundle-analyzer -D
复制代码
  • clean-webpack-plugin 这个插件主要是用来清除上一次打包的内容,由于每次打包文件后面会生成新的hash值,不及时清除dist目录会累积不少文件,还容易形成没必要要的麻烦。
  • copy-webpack-plugin 有时候咱们存在静态资源,也就是不参与打包的文件,这时候咱们就须要这个插件来实现拷贝,保证资源可访问。
  • @intervolga/optimize-cssnano-plugin 分离出来的css文件进行压缩。
  • mini-css-extract-plugin 用于把css单独分离出来。
  • webpack-merge 合并webpack配置的插件。
  • webpack-bundle-analyzer 打包事后能够看到各个js文件所占的大小以及在项目中的比例。

接下来修改相关的文件

6.一、webpack.config.js

注:这儿我把miniCssExtractPlugin放在通用配置文件里面了,开发和生产都使用,这里格式有点乱了-_-!

// build/webpack.config.js
// node.js里面自带的操做路径的模块
const path = require("path");
// 引入htmlWebpackPlugin自动导入js文件
const htmlWebpackPlugin = require('html-webpack-plugin');
// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin');
// 用于提取css到文件中
const miniCssExtractPlugin = require('mini-css-extract-plugin');
// 用于压缩css代码
const optimizeCssnanoPlugin = require('@intervolga/optimize-cssnano-plugin');
// 拷贝静态资源
const copyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  // webpack打包的入口文件
  entry: {
    main: path.resolve(__dirname, "../src/main.js")
  },
  // webpack打包的输出相关的额配置
  output: {
    // 打包事后的文件的输出的路径
    path: path.resolve(__dirname, "../dist"),
    // 打包后生成的js文件,带hash值来保证文件的惟一性
    filename: "js/[name].[hash:4].js",
    // 生成的chunk文件名
    chunkFilename: "js/[name].[hash:4].js",
    // 资源的引用路径(这个跟你打包上线的配置有关系)
    publicPath: "/"
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }	
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: miniCssExtractPlugin.loader, // 使用miniCssExtractPlugin.loader代替style-loader
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader'
          }
        ]
      },
      {
				test: /\.(jpe?g|png|gif)$/i,
				use: [
					{
						loader: 'url-loader',
						options: {              
              limit: 5120, // 当文件大于5kb时走file-loader相关的配置             
              esModule: false, // 这个参数要设置成false,否则生成图片的路径时[object Module]              
              fallback: 'file-loader', // 当文件大于5kb时走file-loader相关的配置
              name: 'images/[name].[hash:4].[ext]' // 生成的路径和文件名
						}
					}
				]
			},
      {
				test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
				use: [
					{
						loader: 'url-loader',
						options: {
              limit: 5120,
              esModule: false,
              fallback: 'file-loader',
              name: 'media/[name].[hash:4].[ext]'
						}
					}
				]
			},
			{
				test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
				use: [
					{
						loader: 'url-loader',
						options: {
              limit: 5120,
              esModule: false,
              fallback: 'file-loader',
              name: 'fonts/[name].[hash:4].[ext]'
						}
					}
				]
      },
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                preserveWhitespace: false
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new htmlWebpackPlugin({
      // 指定模板
      template: path.resolve(__dirname, '../public/index.html'),
      // 输出的文件
      filename: path.resolve(__dirname, '../dist/index.html')
    }),
    new VueLoaderPlugin(),
    // 新建miniCssExtractPlugin实例并配置
    new miniCssExtractPlugin({
      filename: 'css/[name].[hash:4].css',
      chunkFilename: 'css/[name].[hash:4].css'
    }),
    // 压缩css
    new optimizeCssnanoPlugin({
      sourceMap: true,
      cssnanoOptions: {
        preset: ['default', {
          discardComments: {
            removeAll: true,
          },
        }],
      },
    }),
    // 拷贝静态资源
    new copyWebpackPlugin([{
      from: path.resolve(__dirname, '../public'),
      to: path.resolve(__dirname, '../dist')
    }])
  ],
  resolve: {
		alias: {
      // 写了这句,咱们能够这样写代码 import Vue from 'vue'
      'vue$': 'vue/dist/vue.runtime.esm.js',
      // 写了这句,咱们能够这样写代码 import api from '@/api/api.js',省去处处找路径定位到src的麻烦
      '@': path.resolve(__dirname, '../src')
    },
    // 添加一个 resolve.extensions 属性,方便咱们引入依赖或者文件的时候能够省略后缀
    // 咱们在引入文件时能够这样写 import api from '@/api/api'。
    extensions: ['*', '.js', '.vue']
	}
};
复制代码

6.二、webpack.dev.js

// build/webpack.dev.js
// 引入webpack
const webpack = require('webpack');
// 引入webpack通用配置
const webpackCommonConfig = require('./webpack.config.js');
// 引入配置合并插件
const merge = require('webpack-merge');

module.exports = merge(webpackCommonConfig, {
  // 指定模式,这儿有none production development三个参数可选
  // 具体做用请查阅官方文档
  mode: "development",
  plugins: [
    // 辅助HotModuleReplacementPlugin插件
    new webpack.NamedModulesPlugin(),
    // 启用热更新必须的
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    // 默认状况不设置这个只能经过localhost:9000来访问,如今能够经过本机局域网ip来访问,
    // 好比192.168.12.21:9000,手机在这个局网内也能够访问
    host: '0.0.0.0',
    hot: true,
    port: 9200,
    contentBase: './dist'
  }
});
复制代码

6.三、webapck.prod.js

// build/webpack.prod.js
// 引入清除打包后文件的插件(最新版的须要解构,否则会报不是构造函数的错,并且名字必须写CleanWebpackPlugin)
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// 引入配置合并插件
const merge = require('webpack-merge');
// 引入通用配置
const webpackCommonConfig = require('./webpack.config.js');
// 分析打包后模块分析插件
const webpackBundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = merge(webpackCommonConfig, {
  // 指定模式,这儿有none production development三个参数可选
  // 具体做用请查阅官方文档
  mode: "production",
  plugins: [
    new CleanWebpackPlugin(),
    new webpackBundleAnalyzer({
      analyzerMode: 'static'
    }),
  ]
});
复制代码

配置好相关文件后咱们再修改下package.json中的scripts:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack-dev-server --config ./build/webpack.dev.js",
  "build": "webpack --config ./build/webpack.prod.js"
},
复制代码

最后

相关配置到这儿就结束了,后期会继续更新优化方面的内容,如代码拆分这些,本篇只是如何来搭建一个环境并跑起来,并无优化相关的内容。若有错误还请你们交流指出,以为不错的话点个赞再走吧!

相关代码我已经提交到仓库了,连接地址

相关文章
相关标签/搜索