WEB开发

从零开始撸一个webpack脚手架(1)基本配置

2019-05-20  本文已影响0人  情有千千节

webpack脚手架

gitee地址

介绍

从零搭建一个基于webpack的脚手架,暂时没有配置vue或者react,会在后续拓展

软件环境

 - node         10.15.3
 - yarn         1.16.0
 - webpack      4.31.0
 - webpack-cli  3.3.2

基本配置步骤

  1. yarn init 初始化

  2. 新建基本目录

  mkdir build
  mkdir src
  touch src/index.js              // windows 使用echo ./src/index.js
  touch build/webpack.base.config.js   // windows 使用echo ./build/webpack.base.config.js
  touch build/webpack.dev.config.js    // windows 使用echo ./build/webpack.dev.config.js
  touch build/webpack.prod.config.js   // windows 使用echo ./build/webpack.prod.config.js
  1. 安装webpck webck-cli
  yarn add webpack webpack-cli -D

  1. 新建.gitignore
.gitignore
  node_modules
  1. 配置webpack基本配置文件
yarn add webpack-merge -D

>>>>>>   webpack.base.config.js

const path = require('path')

module.exports = {
    mode: "development",
    entry: {
        //  配置文件的入口
        main: '../src/index.js'
    },
    output: {
        // 打包文件的出口
        path: path.resolve(__dirname, '../dist'),
        // 生成的js文件名称
        filename: 'js/[name].[contenthash:8].js'
    }
}

>>>>>>   webpack.dev.config.js
const path = require('path')
const merge = require ('webpack-merge')
const config = require('./webpack.base.config')
const devConfig = {
    mode: "development"
}

module.exports = merge(config, devConfig)

>>>>>>   webpack.prod.config.js

const merge = require ('webpack-merge')
const config = require('./webpack.base.config')
const prodConfig = {
    mode: "production"
}

module.exports = merge(config, prodConfig)
  1. 开发环境配置webpack-dev-server和代理
yarn add webpack-dev-server

webpack.dev.config.js

devServer: {
  host: "localhost",
  hot: true,
  open: true,
  port: 8080,
  contentBase: '../dist',
  proxy: {
    '/api': {
      target: 'http://192.168.0.106',
      changeOrigin: true,
      pathRewrite: {
        '^/api': ''
      }
    }
  }
}

  1. 配置script
package.json

  "script": {
    "build": "webpack --config ./build/webpack.prod.conf.js",
    "dev": "webpack-dev-server --config ./build/webpack.dev.config.js",
  }

  1. 配置 css-loader sass-loader postcss-loader
yarn add style-loader css-loader sass-loader postcss-loader autoprefixer -D

// postcss-loader autoprefixer 用于添加css3前缀
  {
    test: /\.(sass|scss)$/,
    use: [
      {
        loader: "style-loader" // 将 JS 字符串生成为 style 节点
      },
      {
        loader: "css-loader", // 将 CSS 转化成 CommonJS 模块
        options: {
          importLoaders: 2  // 识别在sass文件中的引用的sass文件,防止不通过sassloader直接走cssloader
        }
      },
      {
        loader: "sass-loader", // 将 Sass 编译成 CSS
        modules: true, // 使用css modules
        localIdentName: '[local]--[hash:base64:8]'
      },
      'postcss-loader'
    ]
  },
  {
    test: /\.css$/,
    use: [
      'style-loader',
      'css-loader',
      'postcss-loader'
    ]
  }

根目录新建 .postcssrc 

module.exports = {
  "plugins": {
    "autoprefixer": {}
  }
}

  1. 使用url-loader解析图片,字体,多媒体文件
yarn add url-loader

{
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  loader: 'url-loader',
  options: {
    limit: 10000,
    name: 'img/[name].[hash:7].[ext]'
  }
},
{
  test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
  loader: 'url-loader',
  options: {
    limit: 10000,
    name: 'media/[name].[hash:7].[ext]'
  }
},
{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url-loader',
  options: {
    limit: 10000,
    name: 'fonts/[name].[hash:7].[ext]'
  }
}
  1. 使用babel-loader 解析js文件,并es6转es5
yarn add babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env -D

根目录新建 .babelrc 文件
{
  test: /\.js$/,
  exclude: /node_modules/,
  loader: 'babel-loader' 将代码与babel联系起来
}

.babelrc 
{
  "presets": ["@babel/preset-env"]  // 用于将es6转es5 翻译规则
}

<!-- babel-loader只会将 ES6/7/8语法转换为ES5语法,但是对新api并不会转换。 -->
解决方法
a. 使用@babel/polyfill ,@babel/polyfill对代码具有侵入性,会污染全局环境,如果是开发插件,UI库类建议使用方案b

yarn add @babel/polyfill core-js@3 -D

.babelrc

{
  "presets": [
    ["@babel/preset-env",
      {
        "useBuiltIns": "usage", // 根据代码按需引入@babel/polyfill 以减小打包大小
        "corejs": 3
      }
    ]
  ]
}

b. 使用@babel/plugin-transform-runtime

yarn add @babel/plugin-transform-runtime @babel/runtime @babel/runtime-corejs2 -D

删除presets使用plugins
.bablrc {
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": 2,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
      }
    ]
  ]
}
  1. 配置sourcemap

sourcemap主要的功能是方便调试,将打包后的代码映射到源文件

webpack.config.dev.js
  devtool: "cheap-module-eval-source-map"

webpack.config.prod.js
  devtool: "none"
  1. 配置 Htmlwebpackplugin

HtmlWebpackPlugin 会在打包后,自动生成一个html文件,并把打包生成的js自动引入到这个html文件中

yarn add HtmlWebpackPlugin -D

webpack.base.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

plugins: [
  new HtmlWebpackPlugin({
    // 指定一个模板文件,生成的html按照这个模板来
    template: path.resolve(__dirname, '../public/index.html')
  })
]
  1. 使用cleanWebpackPlugin
yarn add cleanWebpackPlugin -D

webpack.base.config.js
const CleanWebpackPlugin = require('clean-webpack-plugin');

plugins: [
  new CleanWebpackPlugin()
]
  1. 开启hrm

模块刷新,不会刷新页面

webpack.dev.config.js
const webpck = require('webpack)

devServer: {
  hot: true,
  hotOnly: true
}

plugins: [
  new webpack.HotModuleReplacementPlugin()
]
  1. 配置 tree shaking

只支持 es module 模块的引入 即 import 静态引入, 不支持common.js的 require
生产环境自己会默认配置
主要作用是打包时根据引用来按需打包,对于没有用到的不会打包

webpack.base.config.js

optimization: {
  userExports: true;
}

package.json

"sideEffects": false  或者为数组,标记出不需要tree shaking的
  1. code splitting

对代码进行拆分,防止只打包成一个js文件

webpack.base.config.js

optimization: {
  // 代码分割
  splitChunks: {
    chunks: 'all',
    cacheGroups: {  /*缓存组,对于引入的node_modules中的 全打包进vendors.js 自己写的打包进common.js */
        vendors: {
          test: /[\\/]node_modules[\\/]/,
                    priority: -10, // 优先级
                    filename: 'js/vendors.js'
        },
        default: {
          priority: -20,
                    reuseExistingChunk: true, // 忽略已经打包过的
                    filename: 'js/common.js'
        }
      }
  }
},
  1. 使用@babel/plugin-syntax-dynamic-import 支持动态导入
yarn add @babel/plugin-syntax-dynamic-import -D

.babelrc

"plugins": ["@babel/plugin-syntax-dynamic-import"]
  1. 使用preloading prefetching

webpak希望我们打包多采用异步引入,这样的话打开页面的话代码利用率比较高,暂时没用到的就先没引入。
一些异步的放到后续触发加载,但是会有可能卡顿,所以可以采取preloading ,在 主要的加载完成,带宽释放后,去加载需要预加载的

preloading: 和核心代码一起加载
prefetching: 等核心代码加载完加载
<!-- 使用magic 注释 -->
import(/*webpackPrefetch: true*/ ./handle.js).then(res=>{res.name})
  1. css文件单独抽离

之前看网上很多都是直接配置到生产环境,因为开发环境不支持hrm,现在已经支持hrm了,所以统一配置

<!-- 定义环境变量 -->
webpack.dev.config.js
plugins: [
  new webpack.DefinePlugin({
    'process.env.NODE_ENV':  JSON.stringify('development')
  })
]
webpack.prod.config.js
plugins: [
  new webpack.DefinePlugin({
    'process.env.NODE_ENV': JSON.stringify('production')
  })
]


yarn add mini-css-extract-plugin -D

webpack.bash.config.js
plugins: [
  new MiniCssExtractPlugin({
    filename: 'css/[name].[contenthash].css',
    chunkFilename: 'css/[name].[contenthash].chunk.css'
  })
]

将scss css 中的style-loader更换为
{
  loader: MiniCssExtractPlugin.loader,
  options: {
    hmr: process.env.NODE_ENV === 'development',
  }
},
  1. css压缩
yarn add optimize-css-assets-webpack-plugin -D

webpack.prod.config.js

const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

optimization: {
  minimizer: [
    new OptimizeCssAssetsPlugin({})
  ]
}
  1. 文件路径优化
webpack.dev.config.js
const path = require('path')

resolve: {
  extensions: ['.js', '.jsx'],
  alias: {
    '@': path.join(__dirname, '../src/components'),
  }
},
  1. 单页路由问题
webpack.dev.config.js
devServer : {
  historyApiFallback: true
}
  1. js 压缩
yarn add uglifyjs-webpack-plugin -D

webpack.prod.config.js
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
  minimizer: [
    new UglifyJSPlugin()
  ]
  1. 统一引入css变量
yarn add -D sass-resources-loader

{
  test: /\.scss$/,
  use: [
    { loader: 'vue-style-loader' },
    { loader: 'css-loader', options: { sourceMap: true } },
    { loader: 'sass-loader', options: { sourceMap: true } },
    { loader: 'sass-resources-loader',
      options: {
        sourceMap: true,
        resources: [
          resolveFromRootDir('src/styles/variables.scss'),
        ]
      }
    }
  ]
}
上一篇 下一篇

猜你喜欢

热点阅读