美文网首页
webpack配置多页面实践

webpack配置多页面实践

作者: 0月 | 来源:发表于2020-03-11 20:07 被阅读0次

需求

最近公司又开发一个app,本来没我前端啥事的,需求评审都没我份,我也懒得参加,可是开发到半路,需求改来改去后,还是要前端写两个h5页面配合一下。一个h5邀请注册页面,一个app下载页面,页面很简单,活不多,用框架又增加打包体积,想来想去还是亲手用原生js和配置webpack来搞定它吧,考验脱离框架、库开发出精简业务代码的时候到了。

为什么要用webpack?
理由:

  1. 为了项目可持续化、可维护、可扩展等也就是我们经常说的前端工程化。webpack可以说是前端工程化进程的产物了,里面种种好处不一一列举,以前那种手写html\css\js的年代一去不复返了,那种弊端太多了。
  2. 闲的没事干&&巩固一下webpack知识。

设计稿

注册.png
下载.png

架构

webpack多页面配置,js语法es6,样式预处理器scss。
环境要区分development,test,production三个环境。其中development是我们启动webpack-dev-server开发的环境,test是打包到测试环境,production是打包到线上环境,因为注册页面有两个接口,一个发送验证码,一个注册接口。

webpack基本配置概念:

entry配置入口文件js,
output配置出口,
loader处理各种文件格式转换,
plugin在特定钩子处理文件的流向和位置

wenpack配置分三个文件:
webpack.base.js 公共配置,所有环境都一样
webapck.dev.js 开发环境特有配置
webpack.pro.js 打包特有配置,包括打包到test,production这两个环境
在package.json加三个命令行

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./webpack.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config ./webpack.pro.js",
    "build-test": "cross-env NODE_ENV=test webpack --config ./webpack.pro.js"
  },

执行命令
yarn dev 或者 npm run dev启动开发环境
yarn build 或者 npm run build打包到生产环境也就是production环境
yarn build-test 或者 npm run build-test打包到测试环境

看到这里你会发现我用NODE_ENV这个变量来区分各个环境的
同时还要在webpack.base.js配置webpack.DefinePlugin把变量注入进去

plugins: [
new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV) // 提取package.json中的NODE_ENV变量注入webpack区分开发、测试、生产环境
      }
    })
]

然后在代码中可通过process.env.NODE_ENV来判断,如每个环境api的前缀不一样

let baseurl 
const env = process.env.NODE_ENV
console.log(env)
if (env === 'development') {
// 开发环境
baseurl  = 'http://a.com'
} else if (env === 'test') {
//测试环境
baseurl  = 'http://b.com'
 } else {
// 生产环境
baseurl  = 'http://c.com'
 }

配置多页面

多页面其实就是多个入口,多出口,想明白这点也就简单了,先看目录结构src/pages下面有两个目录。download,register这两个页面的源码、资源都在自己的目录里面

目录结构.png

然后webpack.base.js配置两个入口,一个download一个register

entry: {
    download: './src/pages/download/index.js',
    register: './src/pages/register/index.js'
  },

和配置一个插件 html-webpack-plugin

plugins: [
    new HtmlWebpackPlugin({
      template: 'src/pages/download/index.html',
      filename: 'download.html',
      chunks: ['download'] // 提取注入html的js文件
    }),
   new HtmlWebpackPlugin({
      template: 'src/pages/register/index.html',
      filename: 'register.html',
      chunks: ['register'] // // 提取注入html的js文件
    }),
  new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV) // 提取package.json中的NODE_ENV变量注入webpack区分开发、测试、生产环境
      }
    })
]

其中主要是 配置 chunks: ['register']这里,因为打包的时候会生成register.js和download.js,如果你不指定chunks的话,所有的js都会注入到html模板里面去,我们的需求是register.html只要register.js而download.html只要download.js
这样就配置多页面成功了!

其他常规配置:
打包时es6转es5
scss处理:开发时配置与打包配置不一样
图片处理
js,css压缩处理
代码贴出来在下面让大家参考一下
webpack.base.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const webpack = require('webpack')

module.exports = {
 entry: {
   download: './src/pages/download/index.js',
   register: './src/pages/register/index.js'
 },
 module: {
   rules: [
     {
       test: /\.js$/,
       exclude: /node_modules/,
       loader: 'babel-loader',
       options: {
         presets: [// presets使用于一般的业务项目中,不适于库、框架的研发项目,因为babel-polyfill会污染全局
           [
             "@babel/preset-env",
             {
               "useBuiltIns": "usage", // 只加入用到的es6新特性
               "corejs": 2
             }
           ]
         ]
       }
     },
     {
       test: /\.(jpe?g|png|gif)$/,
       use: {
         loader: 'url-loader', // 默认直接生成base64
         options: {
           name: '[name].[hash:5].[ext]',
           outputPath: 'img/',
           limit: 4 * 1024
         }
       }
     },
     {
       test: /\.(eot|ttf|svg)$/,
       use: {
         loader: 'file-loader',
         options: {
           name: '[name].[hash:5].[ext]',
           outputPath: 'font/'
         }
       }
     }
   ]
 },
 plugins: [
   new HtmlWebpackPlugin({
     template: 'src/pages/download/index.html',
     filename: 'download.html',
     chunks: ['download'] // 提取注入html的js文件
   }),
   new HtmlWebpackPlugin({
     template: 'src/pages/register/index.html',
     filename: 'register.html',
     chunks: ['register']
   }),
   new CleanWebpackPlugin(), // 清除dist目录
   new webpack.DefinePlugin({
     "process.env": {
       NODE_ENV: JSON.stringify(process.env.NODE_ENV) // 提取package.json中的NODE_ENV变量注入webpack区分开发、测试、生产环境
     }
   })
 ],
 resolve: {
   extensions: ['.js'], // 省略.js
   alias: {
     '@': path.resolve(__dirname, 'src')
   }
 }
}

webpack.dev.js

const path = require('path')
const baseConfig = require('./webpack.base')
const merge = require('webpack-merge')

const devConfig = {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map', // 开发环境
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader',
          'postcss-loader'
        ]
      }
    ]
  },
}

module.exports = merge(baseConfig, devConfig)

webpack.pro.js

const baseConfig = require('./webpack.base')
const path = require('path')
const merge = require('webpack-merge')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')

const proConfig = {
  mode: 'production',
  devtool: 'none', // 或者cheap-module-source-map
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js', // 入口文件名
    chunkFilename: '[name].[contenthash].js', // 入口文件引入的其他模块
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
      chunkFilename: '[id].[contenthash].css'
    }) // css提取分割
  ],
  optimization: {
    minimizer: [
      new TerserJSPlugin({}),
      new OptimizeCSSAssetsPlugin({})
    ]
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: false
            }
          },
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: false
            }
          },
          'css-loader',
          'sass-loader',
          'postcss-loader'
        ]
      }
    ]
  }
}

module.exports = merge(baseConfig, proConfig)

其中还有postcss用来配置兼容不同浏览器css的配置
postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

package.json

{
  "name": "yihuo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./webpack.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config ./webpack.pro.js",
    "build-test": "cross-env NODE_ENV=test webpack --config ./webpack.pro.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.6.4",
    "@babel/preset-env": "^7.6.3",
    "autoprefixer": "^9.6.4",
    "babel-loader": "^8.0.6",
    "clean-webpack-plugin": "^3.0.0",
    "core-js": "2",
    "cross-env": "^5.2.1",
    "css-loader": "^3.2.0",
    "file-loader": "^5.1.0",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.8.0",
    "node-sass": "^4.12.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^8.0.0",
    "style-loader": "^1.0.0",
    "url-loader": "^2.2.0",
    "webpack": "^4.41.0",
    "webpack-cli": "^3.3.9",
    "webpack-dev-server": "^3.8.2",
    "webpack-merge": "^4.2.2"
  }
}

其他项目配置优化如
resolve配置
loader配置include\exclude
treeshaking
多进程打包 thread-loader parallel-loader happypack
cache-loader
dll-plugin
splitChunk按需加载等

这里只在webpack.base.js用了resolve配置,杀鸡不用牛刀。

总结

又巩固了一下webpack!

相关文章

网友评论

      本文标题:webpack配置多页面实践

      本文链接:https://www.haomeiwen.com/subject/tllhjhtx.html