我的webpack学习之路(webpack基础开发配置)

我的webpack学习之路(webpack初步认知和webpack基础打包)
我的webpack学习之路(关于webpack的性能优化)

关于我的学习笔记

文章目录

    • 1、webpack开发环境基本配置
    • 2、devServer
    • 3、单独提取css文件
    • 4、css兼容性处理
    • 5、压缩css
    • 6、js语法检查(eslint)
    • 7、js兼容处理
    • 8、压缩html和js代码
    • 9、webpack生产环境基础配置
    • 10、学习期间所有用到的依赖

1、webpack开发环境基本配置

项目目录

---开发环境基本配置
	---src
		---css
			---iconfont.css //阿里矢量图标库下载的素材
			---index.less
		---img
			---1.jpg
		---js
			---index.js
		---other // 阿里矢量图标库下载的素材
			--- iconfont.eot
			--- iconfont.svg
			--- iconfont.ttf
			--- iconfont.woff
	---webpack.config.js

webpack.config.js配置

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
function resolve(dir) {
     
  return path.join(__dirname, dir)
}

module.exports = {
     
  entry: './src/js/index.js',
  output: {
     
    filename: 'js/build.js', // 在build下创建js文件夹,输出build.js
    path: resolve('build')
  },
  module: {
     
    rules: [
      // 处理less样式文件
      {
     
        test: /\.less$/,
        use: [ 'style-loader','css-loader', 'less-loader']
      },
      {
     
        test: /\.css$/,
        use: [ MiniCssExtractPlugin.loader ,'css-loader']
      },
      // 处理css图片资源
      {
     
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',
        options: {
     
          limit: 8 * 1024,
          outputPath: 'img' // 在build下创建img文件夹,放入处理过后的图片
        }
      },
      // 处理html图片资源
      {
     
        test: /\.html$/,
        loader: 'html-loader'
      },
      // 处理其他资源
      {
     
        exclude:/\.(html|css|js|less|jpg|png|gif)$/,
        loader: 'file-loader',
        options:{
     
          outputPath: 'other'// 在build下创建other文件夹,放入处理过后的其他资源(我这里主要是字体资源)
        }
      }
    ]
  },
  plugins: [
    //处理html模板
    new HtmlWebpackPlugin({
     
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
     
      filename: 'css/build.css' // 在build下创建css文件夹,放入处理过后的其他资源
    })
  ],
  mode: 'development'
}

2、devServer

​ 能帮助我们开发时有修改代码,不用一次又一次重新打包编译,会帮助我们自动编译

​ 这里需要webpack-dev-server,需要下载

npm i webpack-dev-server -D

// webpack.condig.js

// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新)
// 特点只会在内存中编译打包,不会有任何输
// 启动devServer指令为npx webpack-dev-server
devServer: {
     
    // 代表运行的项目目录
    contentBase: resolve(__dirname, 'build'),
    // 启动gizp压缩
    compress:true,
    // 端口号
    prot: 9000
}

3、单独提取css文件

使用mini-css-extract-plugin插件

​ 在处理css文件时,用到了两个loaderstyle-loadercss-loader

​ css-loader是处理css文件写到js文件中。再由style-loader在html中创建style标签写入样式。

​ 而mini-css-extract-plugin是从js文件中提取css样式,单独处理到css文件中,所以不需要再使用style-loader。mini-css-extract-plugin里内置了处理css文件的loader,替换掉style-loader即可

const MiniCssExtractPlugin = reuqire('mini-css-extract-plugin')

// 替换style-loader
// 'style-loader' => MiniCssExtractPlugin.loader

// 在plugins中添加插件
new MiniCssExtractPlugin()

// 对输出的css文件的位置和名字处理
new MiniCssExtractPlugin({
     
    // 输出到对应出口文件下,创建css文件夹放入输出的名为build.css问文件
	filename: 'css/build.css'
})

打包处理后的html文件会自动映入css下的build.css

4、css兼容性处理

webpack对css进行兼容处理如要用到一个库:postcss => postcss-loader post-preset-env

这里需要npm下载这两个包,然后就可以在webpack.config.js中处理

npm i  postcss-loader post-preset-env -D
// webpack。config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
function resolve(dir) {
     
  return path.join(__dirname, dir)
}

// 设置node环境变量,修改默认,使兼容处理以开发模式为准
process.env.NODE_ENV = 'development'

module.exports = {
     
  entry: './src/js/index.js',
  output: {
     
    filename: 'js/build.js',
    path: resolve('build')
  },
  module: {
     
    rules: [
      {
     
        test: /\.css$/,
        use: [ 
          MiniCssExtractPlugin.loader,
          'css-loader',
          // css兼容处理需要使用一个库:postcss => postcss-loader postcss-preset-env
          // postcss-preset-env这个插件能帮助我们识别某些环境,从而加载某些配置,能让我们的兼容性精确的浏览器的某一个版本
          // 帮助postcss找到package.json中browserlist里面的配置,透过配置加载制定的css兼容性样式


          /**
           *  "browserslist": {
           *  开发环境 --> 设置node环境变量: process.env.NODE_ENV = development
                "development": [
                  "last 1 chrome version",
                  "last 1 firefox version",
                  "last 1 safari version"
                ],
                "production": [
                  生产环境:默认看生产环境
                  ">0.2%",
                  "not dead",
                  "not op_mini all"
                ]
              }
           */

          // 使用loader的默认配置
          // 'postcss-loader'
          // 修改loader配置
          {
     
            loader: 'postcss-loader',
            options: {
     
              postcssOptions: {
     
                plugins: [['postcss-preset-env', {
     }]]
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    //处理html模板
    new HtmlWebpackPlugin({
     
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
     
      filename: 'css/build.css'
    })
  ],
  mode: 'development'
}

webpack.config.js配置好了还需要配置browsetslist: {}

关于browsetslist的具体配置可以到GitHub上搜索

"browserslist": {
     
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  }

关于post-preset-env配置browserslist,版本不同也有不同的配置,可以自行搜索其他配置方法

5、压缩css

压缩css只需要用到一个插件:optimize-css-assets-webpack-plugin

只需要在webpack.config.js中使用这个插件就可以

// 先引用
const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

//使用
plugins: [
    ... // 其他插件
    new optimizeCssAssetsWebpackPlugin()
]

如上配置完成后就可以运行webpack处理,压缩css文件了

6、js语法检查(eslint)

首先进行js语法检查是借助loader,所以需要想在相应依赖。eslint-loader,这个loader又依赖eslint这个库。

注意:eslint只检查自己写的代码,第三方库是不检查的

设置规则:

​ 在package.json添加eslintConfig配置

"eslintConfig": {
     
   "extends": "airbnb-base"
}

​ 推荐使用airbnb规则,airbnb对应需要的依赖: eslint-config-airbnb-base、eslint、eslint-plugin-import

airbnb规则可以在GitHub上查看详细规则,对应使用的依赖是使用方法可以在npmjs.com中搜索eslint

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require('path');

function resolve(dir) {
     
  return path.join(__dirname,dir)
}
module.exports = {
     
  entry: './src/js/index.js',
  output: {
     
    filename: 'js/build.js',
    path: resolve('build')
  },
  module: {
     
    rules: [
      {
     
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules内的第三方库,不检查,会报错
        loader: 'eslint-loader',
        options: {
     
          // 自动修复eslint错误
          fix: true
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
     
      template: './src/index.html'
    })
  ],
  mode: 'development'
}

设置了fix:true会在源代码中自动修复格式错误

在使用airbnb规则,在js中使用console.log()时会爆出警告,但不会影响运行,这里需要借助eslint-disable-next-line来告诉eslint这下一行eslint规则失效,eslint-disable-next-line是以注释的方式使用

// 下一行eslint所有规则都失效
// eslint-disable-next-line
console.log('hello eslint'); // 这一行eslint的规则就不会生效

7、js兼容处理

首先js兼容性处理需要用到三个依赖:babel-loader、@babel/preset-env、@babel/core

npm i babel-loader @babel/preset-env @babel/core -D

js兼容处理总的来说有三种方法:

1、基本的js兼容处理:—> @babel/preset-env;

// index.js
const add = (x,y) => {
     
    return x + y
}
console.log(add(1,2))

const promise = new Promise((resolve) => {
     
  setTimeout(() => {
     
    console.log('aaaaaaaaaaaa')
    resolve()
  }, 1000)
})
console.log(promise)
module: {
     
    rules: [
        {
     
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
     
                //  预设:指示babel做怎样的兼容性处理
                presets: ['@babel/preset-env'] // 这里做了一个基本的预设环境的兼容性处理
            }
        }
    ]
}

如上在loader中配置babel就做好了一个简单兼容性处理,运行webpack命令后,查看输出的js文件

我的webpack学习之路(webpack基础开发配置)_第1张图片

会看到const被转为var,箭头函数被转为function等兼容性写法

问题:这种方法只能转换基本语法,如promise等高级语法是不能转换的,如上图,promise没有被转换,指示还是只转换了const和箭头函数

2、全部js兼容性处理 ---->@babel/polyfill

全部兼容性处理需要用到@babel/polyfill这个依赖

npm i @babel/polyfill -D

使用方法:

​ 不需要在webpack.config.js中引用,而是在js文件中引用,如下

// index.js

import '@babel/polyfill'


const add = (x,y) => {
     
    return x + y
}
console.log(add(1,2))

const promise = new Promise((resolve) => {
     
  setTimeout(() => {
     
    console.log('aaaaaaaaaaaa')
    resolve()
  }, 1000)
})
console.log(promise)

import引用后即可,运行webpack打包后,打开build.js(打包后的js文件)。就会发现build.js文件体积变大,其中多了很多兼容处理。这是因为@babel/polyfill,将所有兼容性处理全部引入进来了,比较暴力的处理方法

问题:我们只需要解决我们需要的兼容处理,如果将所有兼容代码全部引入,文件体积变大

3.js兼容处理按需加载 ---->core-js

npm i core-js -D

注意:这种方法不能和第二种方法同时使用,需要注释掉@babel/polyfill的引用

配置如下

module: {
     
    rules: [
        {
     
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
     
                presets: [
                    [
                        '@babel/preset-env',
                        {
     
                            // 按需加载
                            useBuiltIns: 'usage',
                            // 指定core-js版本
                            corejs:{
     
                                version: 3
                            },
                            // 指定兼容性做到那个版本的浏览器
                            targets:{
     
                                chrome: '60',
                                firefox: '60',
                                ie: '9',
                                safari: '10',
                                edge: '17'
                            }
                        }
                    ]
                ]
            }
        }
    ]
},

注意:presets的配置,和第一种方法有些不一样:presets:[ [ …这里写loader配置 ] ],两个数组

然后运行webpack命令就可以做到兼容性按需加载了~

8、压缩html和js代码

这两部分的压缩很简单

首先js代码压缩:生产环境下(mode:‘droduction’),会自动压缩js代码

mode: 'droduction'

在我的webpack学习之路(webpack初步认知和webpack基础打包)介绍的webpack的五个核心概念中的mode中知道在生产环境下,会加载很多插件,其中有一个插件为UglifyJsPlugin会自动压缩js代码,无需关注其他

然后是压缩html代码:这里我们只需要在HtmlWebpackPlugin插件中添加一个新的配置minify即可

 plugins: [
    new HtmlWebpackPlugin({
     
      template: './src/index.html',
      // 压缩html代码
      minify: {
     
        collapseWhitespace: true, // 移除空格
        removeComments: true, // 移除注释
      }
    })
  ],

如上配置就可以实现html代码压缩

9、webpack生产环境基础配置

const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 单独提取css文件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') // 压缩css
const HtmlWebpackPlugin = require('html-webpack-plugin')

function resolve(dir) {
     
  return path.join(__dirname,dir)
}

/* 
  css兼容性处理
  需要在package.json中定义browserslist配置
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  postcss-loader默认使用生产环境
  通过process.env.NODE_ENV来改变postcss-loade的处理环境
*/
process.env.NODE_ENV = 'production' // node环境变量,决定使用browerlist的那个环境

const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  // 样式兼容
  {
     
    loader: 'postcss-loader',
    options: {
     
      postcssOptions: {
     
        plugins: [['postcss-preset-env', {
     }]]
      }
    }
  }
]

module.exports = {
     
  entry: './src/js/index.js',
  output: {
     
    filename: 'js/build.js',
    path: resolve('build')
  },
  module: {
     
    rules:[
      /* 
        正常来讲,一个文件只能被一个loader处理。
        当一个文件要被对个loader处理,那么一定要指定laoder的执行顺序
          先执行eslint 在执行babel
          因为:1.当代码格式出错时会报错,在网下执行没有意义。2.如果先执行babel,会将转化为es5,eslint也会对es5语法报错
      */
      // 处理js检查...
      // 在package.json添加eslintConfig配置  --->airbnb(为了更加友好和专业使用airbnb规则)
      // "eslintConfig": {
     
      //   "extends": "airbnb-base"
      // }
      {
     
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules,
        loader: 'eslint-loader',
        // 设置优先执行
        enforce: 'pre',
        options: {
     
          fix: true
        }
      },
      // js兼容处理..
      {
     
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
     
          presets: [
            [
              '@babel/preset-env',
              {
     
                // 按需加载
                useBuiltIns: 'usage',
                corejs: {
     version: 3},
                targets: {
     
                  chrome: '60'
                }
              }
            ]
          ]
        }
      },
      // css处理 ....
      {
     
        test: /\.css$/,
        use: [...commonCssLoader]
      },
      // less处理 ....
      {
     
        test: /\.less$/,
        use: [
          ...commonCssLoader,
          'less-loader'
        ]
      },
      // 图片处理 ...
      {
     
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',
        options: {
     
          limit: 8 * 1024,
          outputPath: 'img'
        }
      },
      // html图片处理
      {
     
        test: /\.html$/,
        loader: 'html-loader'
      },
      // 其他文件处理
      {
     
        exclude: /\.(html|css|js|less|jpg|png|gif|less)$/,
        loader: 'url-loader',
        options: {
     
          outputPath: 'other'
        }
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
     
      filename: 'css/build.css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    // 处理html结构
    new HtmlWebpackPlugin({
     
      template: './src/index.html',
      minify: {
     
        removeComments: true,
        collapseWhitespace: true
      }
    })
  ],
  mode: 'production'
}

10、学习期间所有用到的依赖

"devDependencies": {
     
    "@babel/core": "^7.12.3",
    "@babel/polyfill": "^7.12.1",
    "@babel/preset-env": "^7.12.1",
    "babel-loader": "^8.1.0",
    "core-js": "^3.6.5",
    "css-loader": "^5.0.0",
    "eslint": "^7.12.1",
    "eslint-config-airbnb-base": "^14.2.0",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-import": "^2.22.1",
    "file-loader": "^6.2.0",
    "html-loader": "^1.3.2",
    "html-webpack-plugin": "^4.5.0",
    "less": "^3.12.2",
    "less-loader": "^7.0.2",
    "mini-css-extract-plugin": "^1.2.1",
    "optimize-css-assets-webpack-plugin": "^5.0.4",
    "postcss-loader": "^4.0.4",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^2.0.0",
    "url-loader": "^4.1.1",
    "webpack": "^4.44.2",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0",
    "workbox-webpack-plugin": "^5.1.4"
  },

你可能感兴趣的:(学习,前端,webpack)