从零开始配置webpack

118 阅读3分钟

前言

本文出自一名菜鸟实习生,最近在公司闲来无事,毫无学习方向,因leader灵魂一问:你是不是还不懂项目为什么需要打包,固花费两天时间把webpack知识深入研究,并且写下本文方便日后查看!注:学习不能单纯复制文章内容,需要一步一步理解!(代码优化部分还没有完全掌握,有时间再来研究)

webpack详细配置

初始化项目

npm init  //一路默认回车,生成package.json文件

注:package.json文件是npm的说明文件,管理模块的依赖关系

初始化目录

build文件夹--构建服务和webpack配置

  • build.js:webpack打包服务

  • config.js:该文件主要用于配置构建开发环境和生产环境差异化的参数

  • webpackBase.js:此文件主要用于配置构建开发环境和生成环境的通用配置

  • webpackDev.js:该文件主要用于配置构建开发环境

  • webpackPro.js:该文件主要用于配置构建生产环境

src文件夹--项目目录

  • index
    • index.js:项目构建入口文件
    • index.html:项目入口文件
    • index.scss:样式文件
    • index.vue:vue文件
/*index.html*/
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="index"></div>
</body>
</html>
/*index.js*/
import Vue from "vue";
import index from './index.vue'
import "./index.scss"
function f() {
  var aa=3
  console.log(111)
  console.log(aa)
}
f()
new Vue({
  render:h=>h(index)
}).$mount("#index")
/*index.scss*/
*{
  margin: 0;
  padding: 0;
}
html{
  width: 100%;
}
/*index.vue*/
<template>
    <div>2222</div>
</template>

项目依赖安装

webpack系列

  • webpack:是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle

  • webpack-cli: webpack 4+ 版本必须

  • webpack-dev-server:是一个小型的Node.js Express服务器,使用webpack-dev-middleware来服务于webpack的包,除此自外,它还有一个通过Sock.js来连接到服务器的微型运行时。

  • webpack-merge:合并模块,用于合并对象以创建新对象

  npm install webpack webpack-cli webpack-dev-server webpack-merge -D

loader系列

  • css-loader/style-loader/postcss-loader:处理css样式及文件
npm install css-loader style-loader postcss-loader -D
  • vue-loader/vue-template-compiler:加载和转译vue组件
npm install vue-loader vue-template-compiler -D
  • file-loader:将文件发送到输出文件夹,并返回相对url
npm install file-loader -D
  • babel-loader:加载 ES2015+ 代码,使用 Babel 转译为 ES5
npm install babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env -D
  • eslint-loader :使用eslint清理代码
npm install eslint eslint-loader -D
  • sass-loader:加载和转译sass/scss文件
npm install sass-loader node-sass -D

插件系列

  • html-webpack-plugin:可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口
npm install html-webpack-plugin -D
  • friendly-errors-webpack-plugin:可以识别某些类的webpack错误,并清除,汇总并确定优先级,以提供更好的开发人员体验。一款编译提示插件
npm install friendly-errors-webpack-plugin -D
  • mini-css-extract-plugin:基于webpack4功能构建,用于将CSS提取到单独的文件中。它为每个包含CSS的JS文件创建一个CSS文件。它支持CSS和SourceMap的按需加载。
npm install mini-css-extract-plugin -D
  • optimize-css-assets-webpack-plugin:用于优化/最小化css
npm install optimize-css-assets-webpack-plugin -D
  • ora:一款好看的loading插件
npm install ora -D
  • chalk:一款字体颜色插件
npm install chalk -D
  • rimraf:用于删除已打包项目的npm包
npm install rimraf -D

vue系列

  • vue:框架
npm install vue --save

npm脚本命令配置

配置package.json文件

"scripts": {
    "start": "webpack-dev-server --config build/webpackDev.js",
    "build": "node build/build.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

注:

  • 执行npm run build 等于执行 node build/build.js:在本地进行开发

  • 执行npm run start 等于执行 webpack-dev-server --config build/webpackDev.js:打包项目文件进行线上部署

配置文件

开发环境和生产环境的共同需求:

  • 同样的入口、同样的代码处理(loader处理)、同样的解析配置
"use strict"
//引入node path路径模块
let path=require("path")
//引入node fs文件系统模块
const fs=require('fs')
//引入vue模板编译器vue-template-compiler,用于将vue2.0模板预编译为渲染函数,以避免运行时编译开销和csp限制,应与vue-loader搭配使用
let VueloaderPlugin=require("vue-loader/lib/plugin")
//引入插件html-webpack-plugin用于创建html入口文件
const HtmlWebpackPlugin = require('html-webpack-plugin')
//引入插件mini-css-extract-plugin用于抽离出css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//判断是开发环境还是生产环境
const proMode=process.env.Node_ENV=='production'
//拼接路径
function resolve(dir){
  return path.join(__dirname, '..',dir)
}

//配置多页面入口
//获取src/pages下面的所有文件夹
const page=fs.readdirSync(resolve('src/pages'))
let entryArr={}
let htmlplugin=[]
page.forEach(item=>{
  //遍历生成入口文件并存储到entryArr对象中
  entryArr[item]=`./src/pages/${item}/${item}.js`
  //遍历生成相应的html文件存储到htmlplugin数组中
  htmlplugin.push(
    new HtmlWebpackPlugin({
      entryName:item,
      filename: `${item}.html`,
      template: `./src/pages/${item}/${item}.html`,
      //压缩配置
      minify: {
        //删除html注释
        removeComments: true,
        //去除空格
        collapseWhitespace: true,
        //去除属性引号
        removeAttributeQuotes: true
      }
    })
  )
})
module.exports={
  //项目入口文件-webpack从此处开始构建
  entry: entryArr,
  //配置模块解析部分
  resolve: {
    //配置别名映射
    alias: {
      '@': resolve('src'),
      'vue$': 'vue/dist/vue.esm.js',
      '_c':resolve('src/component'),
      '_p':resolve('src/pages'),
      '_w':resolve('src/webgis/components')
    },
    //自动解析文件扩展名(补全文件后缀,从左往右)
    //例:import home from './home',自动补全.js/.vue/.json
    extensions: [".js",".vue",".json"]
  },
  //配置处理模块的规则,配置不同的loader处理不同的文件
  module: {
    rules: [
      //使用babel-loader处理src下所有的js文件,具体babel配置在.babelrc,主要是用来转义es6
      {
        test: /\.js$/,
        loader: "babel-loader",
        include: resolve("src")
      },
      {
        test: /\.js$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [resolve('src')]
      },
      {
        test: /\.vue$/,
        loader: "vue-loader"
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          proMode? MiniCssExtractPlugin.loader : 'style-loader',
          "css-loader",
          "sass-loader",
          'postcss-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          "file-loader"
        ]
      }
    ]
  },
  plugins: [
    new VueloaderPlugin(),
    ...htmlplugin
  ]
}

开发环境的需求:

  • 模块热更新 (本地开启服务,实时更新)
  • sourceMap (方便打包调试)
  • 接口代理  (配置proxyTable解决开发环境中的跨域问题)
  • 代码规范检查 (代码规范检查工具)
//JavaScript严格模式(strict mode) 即在严格条件下运行,不严禁的代码会报错,从而消除语法不合理的怪异行为
"use strict"
//引入webpack配置合并模块,用于合并对象以创建新对象
const merge = require('webpack-merge')
//引入webpackBase通用配置文件
const webpackBase=require('./webpackBase')
//引入config文件的dev开发环境配置部分
const devConfig=require('./config').dev
//引入编译提示的webpack插件
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

module.exports=merge(webpackBase,{
  mode:'development',
  //项目出口,webpack-dev-server生成的包放在内存中,在项目是无法显示
  output:{
    path:'/dist'
  },
  //启动一个express服务器,在本地进行开发
  devServer:{
    //配置代理解决跨域
    proxy:devConfig.proxy,
    //配置主机名
    host:devConfig.host,
    //配置端口号
    port:devConfig.port,
    //开启热加载,代码保存后会自动刷新页面
    hot:true
  },
  //webpack插件数组
  plugins:[
      //
      new FriendlyErrorsPlugin({
        //编译成功提示
        compilationSuccessInfo: {
          messages: [
            `Your application is running here: http://${devConfig.host}:${devConfig.port}`
          ]
        },
        //编译失败提示
        onErrors: function(severity, errors) {
          if (severity !== "error") {
            return;
          }
          const error = errors[0];
          const filename = error.file.split("!").pop();
          console.log(filename + ':' + error.name)
        }
      })
  ]
})

生产环境的需求:

  • 提取公共代码    
  • 压缩混淆(压缩混淆代码,清除代码空格,注释等信息使其变得难以阅读)
  • 文件压缩/base64编码(压缩代码,减少线上环境文件包的大小)
  • 去除无用的代码
//JavaScript严格模式(strict mode) 即在严格条件下运行,不严禁的代码会报错,从而消除语法不合理的怪异行为
"use strict"
//引入node path路径模块
const path=require("path")
//引入webpack配置合并模块,用于合并对象以创建新对象
const merge=require("webpack-merge")
//引入webpackBase通用配置文件
const webpackBase=require("./webpackBase")
//引入config文件中build生产环境配置部分
const buildConfig=require("./config").build
//引入插件mini-css-extract-plugin,用于抽离出css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//引入插件optimize-css-assets-webpack-plugin,用于压缩css文件
const OptimizeCSSPlugin = require("optimize-css-assets-webpack-plugin");
//配置资源路径函数

function assetsPath(_path){
    return path.join('static',_path)
}
module.exports=merge(webpackBase,{
    mode:'production',
    output:{
        path:path.resolve(__dirname,"../dist"),
        filename:assetsPath("js/[name].[contenthash].js")
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename: assetsPath('css/[name].[contenthash].css'),
            chunkFilename: assetsPath('css/[id].[contenthash].css'),
            ignoreOrder: false
        }),
        new OptimizeCSSPlugin(),
    ]
})