webpack4 从0到0.1

181 阅读10分钟

初始化文件夹

yarn init -y

安装webpack、脚手架以及开发服务配置

yarn add webpack webpack-cli webpack-dev-server -D
  • 根目录下创建 webpack.config.js
let path = require('path');

module.exports = {
    mode: 'production',             //模式:这里有两种模式  production(生产模式)(打包后压缩的代码)    
                                                                    // development(开发模式) () 
    devServer: {                            //开发服务器的配置
          port: 3000,                           //端口配置
          contentBase: './build',       // 以 build 目录作为我们的静态服务(直接访问我们的 build 目录,寻找index.html)
            open:true,                                  // 打包完成后,打开浏览器
            progress:true,                          // 显示进度
            compress:true,                          // gzip压缩           
      },    
    entry: './src/index.js',  // 入口(从哪个地方开始打包,也可以配置多个)
    output: {                             //出口
        filename: 'bundle.js',          //打包后的的文件名
        path: path.resolve(__dirname, 'build') 
                                    // __dirname当前文件路径
                                    // path 要求:路径必须是一个绝对路径
                                    // path.resolve() 解析:把相对路径解析成绝对路径。
                                    // path.join() 拼接:把参数路径拼接到一起。
    }
}
  • 编辑package.json
{
  "name": "webpack_demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",  
  "scripts": {              // 这里是添加的脚本                                                             
    "build": "webpack --config webpack.config.js",  // 这个 webpack 是执行的node-modules 里面的 webpack          
    "dev": "webpack-dev-server"                                         //开发服务器配置       
               
  },
  "devDependencies": {
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  }
}
  • 根目录下添加src文件夹,并添加index.js文件
yarn run build
  • 将项目js文件bundle.js打包到build文件夹,默认在build中寻找index.html作为入口文件bundle.js的承载模板,此时需要手动在build文件夹内添加html文件,并在html文件中引入bundle.js。
yarn run dev
  • 将文件打包到内存中, 也需要在build中新建index.html之后才能打开

安装 html 模板插件 (html-webpack-plugin)

yarn add html-webpack-plugin -D
  • 根目录下添加src文件夹,并添加index.js文件
let HtmlWebpackPlugin = require("html-webpack-plugin") //引入 htmlwebpack 插件    
plugins: [                                          //数组, 放着所有的 webpack插件
        new HtmlWebpackPlugin({
            template: './src/index.html',               //模板文件(html文件)的位置
            filename: 'index.html',                         //打包后的文件名字
            minify: {                                                   //压缩 html 文件
                removeAttributeQuotes:true,         //删除属性的双引号
                collapseWhitespace:true                 //折叠空行,变成一行
            },
            hash: true                                                  //引入的文件后添加hash值(一般不用,直接在文件名上加)
        })
]
  • 再运行yarn run dev 或者yarn run build就不必再build文件夹内手动添加html文件了 解析样式
  • webpack 默认是支持 js模块的,那么,我们在入口文件引入样式文件也会被打包到bundl.js,我们要单独引入需要做以下配置。
  • 安装依赖
yarn add css-loader style-loader less less-loader node-sass sass-loader -D
module: {    //模块
        rules: [    //规则数组
                    // loader的特点: 希望单一性(一个loader处理一件事情)
                    // loader 的顺序是从下到上执行
            {
                test: /\.css$/, //用正则来匹配以 css 结尾的文件
                use: [
                    'style-loader',// style-loader 它是把 css 插入到 head 的标签中
                    'css-loader' //css-loader处理css,负责解析@import这种语法的)
                ]
            },
            {
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader' //less转 css
                ]
            },
            {
                test: /\.s(a|c)ss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader' //sass转css
                ]
            }
        ]
    }
  • 此时在src文件夹下边新建style文件夹并新建四个css、less、sass和scss文件,并通过入口文件引入样式, 我们打包后发现这四个文件被分别引入到head标签中

抽离css样式

  • 作用:使样式文件统一打包到一个css中并被引入文件
  • 安装依赖
yarn add mini-css-extract-plugin -D
  • 更改配置
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [ //数组, 放着所有的 webpack插件
        new MiniCssExtractPlugin({
            filename:'main.css', //抽离出来的css的文件的名字
        })
],
  module: { 
        rules: [
          {
                test: /\.css$/, 
                use: [
                    MiniCssExtractPlugin.loader,//这个loader的作用是:抽离出来 css然后用 link 标签引入到 模板文件中
                    {
                        loader: 'css-loader',
                        options: {
                          importLoaders: 1, // 用于配置 css-loader 作用于 @import 的资源之前」有多少个 loader,当前只有 postcss-loader 1个
                        },
                    }
                ]
                        },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                          importLoaders: 2, 
                        },
                      },                   
                    'less-loader',
                ]
            },
            {
                test: /\.s(a|c)ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // 'style-loader',                          //这个是直接放到head标签中,用上边的替换掉
                    {
                        loader: 'css-loader',
                        options: {
                          importLoaders: 2, 
                        },
                      },                    
                    'sass-loader'
                ]
            },
        ]
    }
  • 现在已经变成抽离出来的main.css文件是用link标签来引入的。

自动添加前缀

  • css有些样式为了支持每个浏览器,需要添加前缀
yarn add postcss-loader autoprefixer -D
  • 根目录需要新建一个自动增加前缀插件的配置文件postcss.config.js,这个配置文件里面的内容需要导出自动加前缀的插件:
module: { //模块
        rules: [ //规则
            {
                test: /\.css$/, //用正则来匹配以 css 结尾的文件
                use: [
                    MiniCssExtractPlugin.loader,//这个loader的作用是:抽离出来 css然后用 link 标签引入到 模板文件中
                    'css-loader',
                    'postcss-loader'             // 转化成postcss 借助此来方便自动补全 注:需要在 css-loader之前处理
                ]
                        },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'less-loader' 
                ]
            },
            {
                test: /\.s(a|c)ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // 'style-loader',                          //这个是直接放到head标签中,用上边的替换掉
                    'css-loader',
                    'postcss-loader',
                    'sass-loader' 
                ]
            }
        ]
    },
  • 添加配置文件文件名:postcss.config.js
module.exports = {
    plugins: [require('autoprefixer')],
}
  • 修改package.js,添加browserslist列表来适配
  "browserslist": [
    "defaults",
    "ie >= 10",
    "last 2 versions",
    "> 1%",
    "iOS 7",
    "last 3 iOS versions"
 ]
  • 还有一种写法是在postcss.config.js直接配置(官方不推荐)
module.exports = {
 plugins: [
   require('autoprefixer')({ browsers: 'last 2 versions' })
 ]
}

压缩 js & css代码 & 配置警告信息

  • 安装依赖,使用terser-webpack-plugin不要用uglifyjs-webpack-plugin,uglifyjs-webpack-plugin 最新版本2.x不支持es6
yarn add optimize-css-assets-webpack-plugin terser-webpack-plugin -D
  • 添加配置
let OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
let TerserPlugin = require('terser-webpack-plugin');
performance: {        
        hints: "warning",            // false | "error" | "warning" // 不显示性能提示 | 以错误形式提示 | 以警告...
        maxEntrypointSize: 5000000,  // 开发环境设置较大防止警告,根据入口起点的最大体积,控制webpack何时生成性能提示,整数类型,以字节为单位        
        maxAssetSize: 3000000        // 最大单个资源体积,默认250000 (bytes)
},
optimization: {                                                                             //优化项
        minimizer: [                                                                    //压缩体积
            new TerserPlugin({                            //压缩js
                cache: true,                                                    //是否用缓存
                parallel: true,                                             //是否是并发打包(一起压缩多个)
                sourceMap: true                                             //源码映射
            }),
            new OptimizeCssAssetsWebpackPlugin()                                                //压缩css
        ]
},

使用Babel ES5 -> ES6

  • babel-loader: 是 webpack 和 babel 通讯的桥梁,使 webpack 和 babel 打通,babel-loader 并不会把 js 中的 ES6 语法转换成 ES5 语法
  • @babel/core: 是 babel 的核心语法库,它能够让 babel 识别 js 代码里面的内容并做转化
  • @babel/preset-env: 将 ES6 语法转换成 ES5 语法,它包含了所有 ES6 语法转换成 ES5 语法的翻译规则
  • @babel/preset-react:将jsx语法转换成js
  • @babel/plugin-transform-runtime: 避免 polyfill 污染全局变量,减小打包体积
  • @babel/polyfill: ES6 内置方法和函数转化垫片
  • 安装依赖
yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react -D
yarn add @babel/polyfill -S         
  • 更改配置
 {
   test: /\.(js|jsx)$/,
     exclude: /node_modules/,
       use: [
         {
           loader: "babel-loader"
         }
       ]
 },
  • 根目录添加 .babelrc
{
    "presets": [
      ["@babel/preset-env",
        {
        "targets": {             // 描述您为项目支持/目标的环境
          "node": "current"      // node版本
        },
        "useBuiltIns": "usage",  //按需注⼊
        "corejs": {              //新版本需要指定核⼼库版本
            "version": 3,
            "proposals": true    //启用poly-filling core-js支持的每个ES提案。
        }
        }
    ],
      "@babel/preset-react"
    ]
}
  • babel-polyfill的几种使用方式
  • 1.在入口文件index.js中添加 import '@babel/polyfill'
  • 缺点:全局引入 @babel/polyfill 的这种方式可能会导入代码中不需要的 polyfill,从而使打包体积更大
  • 2.按需引入polyfill,useBuiltIns方式
  • 更改 .babelrc,只转译我们使用到的,将入口文件全局引入这段代码注释掉 // import '@babel/polyfill'
{
    "presets": [
        [
            "@babel/preset-env", 
            {
                "useBuiltIns": "usage",
                "corejs": {
                    "version": 3,
                    "proposals": true
                }
            },            
        ],
      "@babel/preset-react"
    ],    
}
  • 这就配置好了按需引入。配置了按需引入 polyfill 后,用到es6以上的函数,babel会自动导入相关的polyfill,这样能大大减少 打包编译后的体积
  • 3.按需引入polyfill,使用插件 babel-runtime 与 babel-plugin-tranform-runtime方式
yarn add -D @babel-plugin-transform-runtime babel-plugin-transform-react-jsx
yarn add @babel-runtime -S
  • 更改配置
{
    "presets": [
        [
            "@babel/preset-env",             
            "@babel/preset-react"
        ]                
    ]  ,    
    "plugins": [
      "babel/transform-react-jsx", //如果是需要支持 jsx 这个东西要单独装一下。
      "@transform-runtime"
    ],
}

使用 HotModuleReplacement (热模块替换HMR)

  • 建立了开发环境本地服务器 后,当修改内容后,网页会同步刷新
  • 添加新代码
devServer: {
    hot: true
},

plugins: [
    new webpack.HotModuleReplacementPlugin()
],

记录react页面留存状态state,热更新react-hot-loader

  • 安装依赖
yarn add react-hot-loader -D
  • 入口文件更新(需要先安装react和react-dom)
import React from "react";
import ReactDOM from "react-dom";
import { AppContainer } from "react-hot-loader"
import { BrowserRouter } from "react-router-dom";
import Router from "./router";
 
renderWithHotReload(Router);                            //初始化
 
if (module.hot) {                                       //热更新时执行热更新
  module.hot.accept("./router/index.js", () => {
    const Router = require("./router/index.js").default;
    renderWithHotReload(Router);
  });
}
 
 
function renderWithHotReload(Router) {                  //重新渲染的函数
  ReactDOM.render(
    <AppContainer>
      <BrowserRouter>
        <Router />
      </BrowserRouter>
    </AppContainer>,
    document.getElementById("app")
  );
}

处理图片

  • 安装插件file-loader和url-loader,url-loader基于file-loader,所以两个都要安装。
  • 也可以只使用file-loader,url-loader在file-loader的基础上扩展了功能,比如能设置小于多少KB的图片进行base64转码等。
yarn add file-loader url-loader -D
{
  test: /\.(png|jpg|svg|gif|ico)?$/,
    use: [{
      loader: 'url-loader',
      options:{           //这里的options选项参数可以定义多大的图片转换为base64 
        fallback: "file-loader",    // 当文件大小超过limit值,使用file-loader(这是默认项不配也没事)
        limit: 10 * 1024,               // 表示小于10kb的图片转为base64,大于10kb的是路径
        outputPath: 'images',           // 定义输出的图片文件夹
        //publicPath:'http://localhost:3000/'                   //一般图片配置在cdn上,它会去找publicPath + outputPath路径下的img文件,不配置就是根目录下
        name: '[name].[hash:8].[ext]'       //自动生成名称
      }
    }]
},  

打包前先清空输出目录(用在build时)

yarn add clean-webpack-plugin -D
let {CleanWebpackPlugin} = require('clean-webpack-plugin');
new CleanWebpackPlugin(),     //
  • 打包前先清空输出目录,v3版本只能传对象,默认配置值即可。

拷贝静态文件

  • 有时项目中没有引用的文件也需要打包到目标目录
yarn add copy-webpack-plugin -D
new CopyWebpackPlugin([{
  from: path.join(__dirname,'src/public'),//静态资源目录源地址
  to:'./public' //目标地址,相对于output的path目录
}])

代码分割

optimization:{
        splitChunks:{
            chunks:'all',// all异步和同步都分割、async 异步分离、initial初始化分离。
            name:'jquery', //打包后的名字
            minSize:3000, //形成一个新代码块最小的体积        
            minChunks:1,//在分割之前,这个代码块最小应该被引用的次数 
            maxInitialRequests:3, //一个入口最大的并行请求数
            maxAsyncRequests:5, //按需加载时候最大的并行请求数。
            //  此选项允许您指定用于生成名称的分隔符 默认以~分割
            automaticNameDelimiter: '~',
            // 下面是缓存组的配置
            //缓存组会继承splitChunks的配置,
            //但是test、priorty和reuseExistingChunk只能用于配置缓存组。
            cacheGroups: { 
                default: { // 默认缓存组的配置
                    minChunks: 2,
                    //定义缓存组的优先级 更高优先级的缓存组可以优先打包所选择的模块)(默认自定义缓存组优先级为0)
                    priority: -20, 
                    //选项允许复用已经存在的代码块,而不是新建一个新的,需要在精确匹配到对应模块时候才会生效。
                    reuseExistingChunk: true,
                },
                vendors: {
                    //选项用于控制哪些模块被这个缓存组匹配到 默认所有模块
                    // 值得类型RegExp、String和Function
                    test: /[\\/]node_modules[\\/]/, // 这里选的是node_modules中的模块
                    priority: -10 //定义缓存组的优先级
                },
                //splitChunks是拆包优化的重点,第三方组件(组件较大),建议单独拆包,如下所示。
                elementUI: {
                    name: "chunk-elementUI", // 单独将 elementUI 拆包
                    priority: 15, // 权重需大于其它缓存组
                    test: /[\/]node_modules[\/]element-ui[\/]/
                }
            }
        }
    },

源码调试

  • 增加 devtool 源码映射 可以很方便的调试源代码
  • 源码映射 单独生成一个 source-map文件 出错会标识出错的列和行 大和全 devtool:'source-map',
  • 不会单独生成一个文件 但会显示行和列 devtool: 'eval-source-map',
  • 不会产生单独列 但会生成一个映射文件 devtool: 'cheap-module-source-map', //保留 后来调试用
  • 不会单独生成文件 集成在打包文件中 也不产生列 devtool: 'cheap-module-eval-source-map',

watch监视

  • 更改完配置运行yarn run build后,会监控修改文件,会及时将修改同步到build日常开发一般不用
//监控 实时打包   类似node里边那个实时监控的
  watch: true,
  //监控的选项
  watchOptions: {
    poll: 1000, //每秒问1000次
    aggregateTimeout: 500 ,//防抖 (类似于函数防抖)
    ignored: /node_modules/ //忽略哪个文件
  },

代理以及mock

devServer: {                               //开发服务器的配置     
        proxy: {        //代理解决跨域 
            "/api": {   //将请求路径中有api的请求转发到target
                target: "http://localhost:3500",          //这个ip
                changeOrigin: true,                       // target是域名的话,需要这个参数,
                pathRewrite: {"^/api": ""},               // 将路径中/api重写为空
                secure: false,                            // 设置支持https协议的代理
            }         
        },      
       
        before(app) { // 前端只想单纯模拟方法提供的方法 相当于钩子,但是一般不这么mock 
            //写这些代码就不存在跨域问题 
            app.get('/user', (req, res) => {
                res.json({
                    name: 'myname-before'
                })
            })
        }
 }

解析、指定拓展名、别名

resolve: {  //解析     
        modules: [path.resolve('node_modules')],    //指定解析的模块,只在当前目录下查找    
        extensions: ['.js','.css','.json'],         // 扩展名,依次尝试查找数组中拓展名结尾的文件,    
        alias: {                                                                //别名
           bootstrap: 'bootstrap/dist/css/bootstrap.css',   //  可以是一个文件
         request: './src/utils/request'//  可以是一个路径
        }
  }

优化项

  • noParse不解析
  • IgnorePlugin忽略包
module: { //模块       
    noParse: /jquery/, //如果import的内容(jquery)不再依赖其它内容,(一般是不再依赖其他的三方库),不去解析它的依赖库 
}
plugins:[
        new webpack.IgnorePlugin(/\.\/locale/,/moment/),
  //在import moment时忽略moment中的local,想使用local时可以引入local中的某个语言
  //这个包我没下,就不演示了
]     
  • happypack多线程打包
yarn add -D happypack os
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        //把对.js 的文件处理交给id为happyBabel 的HappyPack 的实例执行
         use: ['happypack/loader?id=happyBabel'],//这里的id=happyBabel要跟下边的对应        
        exclude: /node_modules/
      },
    ]
  },
plugins: [
    new HappyPack({
        //用id来标识 happypack处理那里类文件
      id: 'happyBabel',//这个id值要跟上面对应
      //如何处理  用法和loader 的配置一样
      loaders: ['babel-loader?cacheDirectory=true'],
     // loaders: [{
     //   loader: 'babel-loader?cacheDirectory=true',
   //   }],
      //共享进程池
      threadPool: happyThreadPool,
      //允许 HappyPack 输出日志
      verbose: true,
    })
  ]
}

环境拆分

  • 根目录新建config文件夹以及在其中创建webpack.base.config.js、webpack.dev.config.js、webpack.prod.config.js
yarn add webpack-merge -D
  • 抽离公共文件,注意改部分配置的路径
let path = require('path');
let webpack = require('webpack');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
let OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
let TerserPlugin = require('terser-webpack-plugin');
let CopyWebpackPlugin = require('copy-webpack-plugin')
let HappyPack = require('happypack');
let os = require('os');
let happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

module.exports = { 
    performance: {        
        hints: "warning",            // false | "error" | "warning" // 不显示性能提示 | 以错误形式提示 | 以警告...
        maxEntrypointSize: 10000000,  // 开发环境设置较大防止警告,根据入口起点的最大体积,控制webpack何时生成性能提示,整数类型,以字节为单位        
        maxAssetSize: 8000000        // 最大单个资源体积,默认250000 (bytes)
    },
    entry:'./src/index.js',
    output:{
        filename:'bundle_[hash:8].js',
        path:path.resolve(__dirname, '../dist')
    },
    optimization: { 														//优化项
        minimizer: [														//压缩体积
            new TerserPlugin({											//压缩js
                cache: true, 												//是否用缓存
                parallel: true, 											//是否是并发打包(一起压缩多个)
                sourceMap: true,                                                //源码映射模式 
                extractComments:false,              
            }), 
            new OptimizeCssAssetsWebpackPlugin()            				//压缩css
        ],
        splitChunks:{
            name:'vendor', //打包后的名字
            chunks:'all',
            minSize:100,  // 默认30000
            //  maxSize:160,
            automaticNameDelimiter: '-', // 将连接符~ 换成 -
            cacheGroups:{
                default: { // 默认缓存组的配置
                    name:'commons',
                    minChunks: 2,
                    //定义缓存组的优先级 更高优先级的缓存组可以优先打包所选择的模块)(默认自定义缓存组优先级为0)
                    priority: -20,
                    //选项允许复用已经存在的代码块,而不是新建一个新的,需要在精确匹配到对应模块时候才会生效。
                    reuseExistingChunk: true,
                },
                query: {
                    //选项用于控制哪些模块被这个缓存组匹配到 默认所有模块
                    // 值的类型RegExp、String和Function
                    test: /[\\/]node_modules[\\/]/, // 这里选的是node_modules中的模块
                    priority: -10 //定义缓存组的优先级
                }
          }
    }
},
    module: { //模块       
        noParse: /jquery/, //如果import的内容不在依赖其它内容,(一般是不再依赖其他的三方库),不去解析它的(jquery)依赖库 
        rules: [ //规则
            {
                test: /\.css$/, //用正则来匹配以 css 结尾的文件
                use: [
                    MiniCssExtractPlugin.loader,//这个loader的作用是:抽离出来 css然后用 link 标签引入到 模板文件中
                    {
                        loader: 'css-loader',
                        options: {
                          importLoaders: 1, // 用于配置 css-loader 作用于 @import 的资源之前」有多少个 loader,当前只有 postcss-loader 1个
                        },
                      },
                    'postcss-loader'             // 转化成postcss 借助此来方便自动补全 注:需要在 css-loader之前处理
                ]
						},
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                          importLoaders: 2, 
                        },
                      },                   
                    'less-loader', //把 less --->转换为 css
                    'postcss-loader',
                ]
            },
            {
                test: /\.s(a|c)ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // 'style-loader',							//这个是直接放到head标签中,用上边的替换掉
                    {
                        loader: 'css-loader',
                        options: {
                          importLoaders: 2, 
                        },
                      },                    
                    'sass-loader' ,//把 sass --->转换为 css
                    'postcss-loader',
                ]
            },
            {
                test: /\.(jsx|js)$/,
                  exclude: /(node_modules|jtopo)/,          //排除文件夹
                    // use: [
                    //   {
                    //     loader: "babel-loader"
                    //   }
                    // ]
                use: ['happypack/loader?id=happyBabel'],//这里的id=happyBabel要跟下边的对应
            }, 
            {
              test: /\.html$/,
              use: {
                loader: 'html-loader'
              }
            },
            {
                test: /\.(png|jpg|svg|gif|ico)?$/,
                use: [{
                    loader: 'url-loader',
                    options: { // 这里的options选项参数可以定义多大的图片转换为base64
                        fallback: "file-loader",
                        limit: 10, // 表示小于10kb的图片转为base64,大于10kb的是路径
                        outputPath: 'images', //定义输出的图片文件夹
                        name: '[name].[ext]'
                    }
                }]
            },    

        ]
    },    
    //插件的配置
    plugins: [                                              //数组, 放着所有的 webpack插件
        new webpack.HotModuleReplacementPlugin(),           //自带热更新插件
        new HtmlWebpackPlugin({
            template: './src/index.html',                   //模板文件(html文件)的位置
            filename: 'index.html',                         //打包后的文件名字
            minify: {                                       //压缩 html 文件
                removeAttributeQuotes:true,                 //删除属性的双引号
                collapseWhitespace:true                     //折叠空行,变成一行
            },
            // hash: true,                                  //模板中自动引入的文件添加hash值(建议自己配,不自动加)
        }),
        new MiniCssExtractPlugin({
            filename:'main_[hash:8].css', 							//抽离出来的css的文件的名字
        }),
        // new CleanWebpackPlugin(),                           // 打包前先清空输出目录
        new CopyWebpackPlugin([
            {
                from: path.join(__dirname,'../src/public'),//静态资源目录源地址
                to:'./public' //目标地址,相对于output的path目录
            },
            {
                from:'./src/jtopo', to:'jtopo'
            }
        ]),
        new HappyPack({ //处理js  
          id: 'happyBabel',//用id来标识 happypack处理那里类文件,这个id值要跟上面对应
          //如何处理  用法和loader 的配置一样
          loaders: ['babel-loader?cacheDirectory=true'],
         // 或者loaders: [{
         //   loader: 'babel-loader?cacheDirectory=true',
         //   }],          
          threadPool: happyThreadPool,//共享进程池          
          verbose: true,//允许 HappyPack 输出日志
        })
    ],    
}
  • 配置开发环境
const merge = require('webpack-merge');
const baseConfig = require('./webpack.base.config.js');
let path = require('path');

module.exports = merge(baseConfig, {
    // 设置为开发模式
    mode: 'development',
    //  'source-map'源码映射 单独生成一个 source-map文件 出错会标识出错的列和行 大和全
    //  'eval-source-map' 不会单独生成一个文件 但会显示行和列
    //  'cheap-module-source-map' 不会产生单独列 但会生成一个映射文件
    //  'cheap-module-eval-source-map'不会单独生成文件 集成在打包文件中 也不产生列
    devtool: 'inline-source-map',              // 增加 devtool调试工具,源码映射 可以很方便的调试源代码  
    // 配置服务端目录和端口
    devServer: {                               //开发服务器的配置
        port: 3000,                            //端口配置
        contentBase: './dist',                // 以 build 目录作为我们的静态服务(直接访问我们的 build 目录,优先本地载从内存找)
        // open:true,                             //启动服务后打开浏览器
        progress: true,                         //进度条
        compress: true,                        //是否启用gzip压缩
        hot: true,                                //热更新           
        // /user的用法   2解决方法
        proxy: {        //代理解决跨域 
            "/api": {   //将请求路径中有api的请求转发到target
                target: "http://localhost:3500",          //这个ip
                changeOrigin: true,                       // target是域名的话,需要这个参数,
                pathRewrite: {"^/api": ""},               // 将路径中/api重写为空
                secure: false,                            // 设置支持https协议的代理
            }         
        },      
    },
        resolve: {	//解析     
            modules: [                       // 优化模块查找路径, 指定解析的模块,只在当前目录下查找    
                path.resolve('src'),
                path.resolve('node_modules') // 指定node_modules所在位置 当你import 第三方模块时 直接从这个路径下搜索寻找
            ],            
            extensions: ['.js','.jsx','.css'],			// 扩展名,依次尝试查找数组中拓展名结尾的文件,    
            alias: {																//别名
                bootstrap: 'bootstrap/dist/css/bootstrap.css',	//	可以是一个文件
                utils: './src/utils'					//	可以是一个路径
            }
      }
    })
  • 配置生产环境
const merge = require('webpack-merge');
const baseConfig = require('./webpack.base.config.js');
let {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports = merge(baseConfig, {	
    mode: 'production',                                     // 设置为生产模式
    devtool: 'cheap-module-source-map',              // 增加 devtool调试工具,源码映射 可以很方便的调试源代码  
    plugins: [                                             
        new CleanWebpackPlugin(),                           // 打包前先清空输出目录       
    ],
    // //监控,实时打包,当代码更改后改动build文件,一般开发时不要用
    // watch: true,
    // //监控的选项
    // watchOptions: {
    //     poll: 1000, //  每秒问1000次
    //     aggregateTimeout: 500 ,//   防抖 (类似于函数防抖,代码改变0.5秒后开始更改)
    //     ignored: /node_modules/ //忽略哪个文件
    // }
});