webpack笔记总结(一)

一、webpack初探

1.webpack究竟是什么?

webpack is a module bundler.

webpack 是一个模块打包器,它的主要目标是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器中使用,但它也能够胜任转换(transform)、打包(bundle)或包裹(package)任何资源(resource or asset)。

2.搭建webpack环境

安装

1.node环境

2.全局安装webpack

npm install webpack webpack-cli -g

webpack -v

全局安装会导致不同webpack版本无法同时启动

3.项目内安装webpack

npm install webpack webpack-cli --save--dev
# === npm install webpack webpack-cli -D

npx 命令

用法:npx + 调用的命令

当我们全局和局部项目都安装了webpack时

npx webpack // 会在当前项目的node_modules中寻找.bin/webpack
webpack // 会调用全局的webpack

npm 从5.2版开始,增加了 npx 命令。

npx 想要解决的主要问题,就是调用项目内部安装的模块。

npx 的原理很简单,就是运行的时候,会到node_modules/.bin路径和环境变量$PATH里面,检查命令是否存在。

由于 npx 会检查环境变量$PATH,所以系统命令也可以调用。

# 等同于 ls
$ npx ls

​ 摘自阮一峰的网络日志

npm script 配置

在package.json文件中配置script,这样我们运行npm run bundle,就会在当前项目寻找webpack命令

{
    
    
  "name": "webpack-demo",
  "scripts": {
    
    
    "bundle": "webpack"
  },
  "devDependencies": {
    
    
    "webpack": "^5.14.0",
    "webpack-cli": "^4.3.1"
  }
}
npm run bundle
# 相当于 npx webpack

3.使用 webpack 的配置文件

webpack默认配置文件名:webpack.config.js

指定配置文件打包

npx webpack --config webpack.my.config.js

webpack.config.js

const path = require('path');

module.exports = {
    
    
  mode: 'development',
  entry: './src/index.js',
  output: {
    
    
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist')
  }
};

二、webpack核心概念

1.什么是loader

webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。

例:打包图片

file-loader 将文件发送到输出文件夹,并返回(相对)URL

npm install file-loader -D

webpack module配置

module.exports = {
    
    
  mode: 'development',
  entry: './src/index.js',
  module: {
    
    
    rules: [
      {
    
     test: /\.jpg$/, use: {
    
     loader: 'file-loader' } }
    ]
  }
};

2.使用loader打包静态资源(图片)

file-loader

将文件发送到输出文件夹,并返回(相对)URL

webpack v4文档,file-loader options

webpack.config.js

module.exports = {
    
    
  module: {
    
    
    rules: [
      {
    
    
        test: /\.(jpg|png|gif)$/,
        use: {
    
     
          loader: 'file-loader',
          options: {
    
    
            // placeholder 占位符
            name: '[name]_[hash].[ext]',
            outputPath: 'images/'
          }
        }
      }
    ]
  }
};

在浏览器中使用

import avatar from './images/avatar.jpg';

const img = new Image();
img.src = avatar;

let root = document.getElementById('root');
root.appendChild(img);

url-loader

webpack v4文档,url-loader

像 file loader 一样工作,但如果文件小于限制,可以返回 data URL;图片大于limit,会生成对应文件。

npm install url-loader -D
module: {
    
    
  rules: [
    {
    
    
      test: /\.jpg$/,
      use: {
    
    
        loader: 'url-loader',
        options: {
    
    
          // placeholder 占位符
          name: '[name]_[hash].[ext]',
          outputPath: 'images/',
          limit: 2048
        }
      }
    }
  ]
}

3.使用Loader打包静态资源(样式)

打包普通css

style-loader将模块的导出作为样式添加到 DOM 中

css-loader解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码

npm install style-loader css-loader -D

webpack.config.js

module.exports = {
    
    
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
};

打包成功会在head标签中插入style标签

打包scss

sass-loader 加载和转译 SASS/SCSS 文件

安装

npm install sass-loader node-sass --save-dev
module: {
    
    
  rules: [
    {
    
    
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader']
    }
  ]
}

当我们打包一个scss文件时,loader是按照从后往前执行,先sass-loader,再css-loader,最后style-loader

使用postcss-loader

PostCSS 利用 JavaScript 的强大编程能力对 CSS 代码进行转换。数以百计的 PostCSS 插件可以用来为 CSS 属性添加特定于浏览器厂商的前缀、支持未来 CSS 语法、模块化、代码检测等。

npm install postcss-loader autoprefixer -D

在项目根目录新建 postcss.config.js,配置使用的插件

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

在打包之后的css自动添加浏览器厂商前缀,如:-webkit-transform

css-loader配置

在scss中引入scss时

这种情况会导致新引入的scss不会走之前的loader,我们需要设置importLoaders

  • 查询参数 importLoaders,用于配置「css-loader 作用于 @import 的资源之前」有多少个 loader。
  • css模块化modules:true。
const path = require('path');

module.exports = {
    
    
  module: {
    
    
      {
    
    
        test: /\.scss$/,
        use: [
          'style-loader',
          {
    
    
            loader: 'css-loader',
            options: {
    
    
              importLoaders: 2,
      		  modules: true
            }
          },
          'sass-loader',
          'postcss-loader'
        ]
      }
    ]
  }
};

打包字体图标

使用file-loader当作静态资源打包

rules: [
  {
    
    
    test: /\.(eot|ttf|svg|woff)$/,
    use: {
    
     
      loader: 'file-loader'
    }
  },
]

阅读webpack文档-资源管理

4.使用plugins让打包更快捷

webpack v4 plugin

plugin 可以在webpack运行到某个时刻的时候,自动帮我们做一些事情。

HtmlWebpackPlugin

HtmlWebpackPlugin简化了HTML文件的创建,以便为你的webpack包提供服务。这对于在文件名中包含每次会随着编译而发生变化哈希的 webpack bundle 尤其有用。 你可以让插件为你生成一个HTML文件,使用lodash模板提供你自己的模板,或使用你自己的loader。

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

npm install --save--dev html-webpack-plugin

配置

const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [new HtmlWebpackPlugin({
    
    
  template: 'src/index.html' // 设置模板
})]

clean-webpack-plugin

打包删除上次打包的结果

npm install clean-webpack-plugin -D

配置

const {
    
     CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [
  new CleanWebpackPlugin()
]

阅读:管理输出

5.Entry与Output的基础配置

配置多个打包文件

entry: {
    
    
  a: './src/index.js',
  b: './src/index.js'
},
output: {
    
    
  // 公共路径
  publicPath: 'http://cdn.com.cn',
  // 输出文件:Template strings占位符
  filename: '[name].js',
  // 输出路径
  path: path.join(__dirname, 'dist')
},

6.SourceMap的配置

Devtool配置

此选项控制是否生成,以及如何生成 source map。

选择一种 source map 格式来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。

sourceMap是一个映射关系

从打包后的文件,找到对应映射的源代码的位置

devtool: 'source-map'

可以生成:bundle.js 和 bundle.js.map

7.使用WebpackDevServer

每次修改完文件,我们都需要重新打包,刷新网页,效率低

做法一:watch监听文件修改

–watch 检测到打包的文件改变时,自动重新打包

在package.json中添加脚本

"scripts": {
    
    
    "bundle": "webpack",
    "watch": "webpack --watch"
  },

做法二:使用devServer

提供一个本地开发服务器

通过 webpack-dev-server 的这些配置,能够以多种方式改变其行为。这是一个简单的示例,利用 gzips 压缩 dist/ 目录当中的所有内容并提供一个本地服务(serve):

安装

npm install webpack-dev-server -D

基本配置

devServer: {
    
    
  contentBase: './dist',
  open: true,
  port: 8080
},

发ajax请求时,要求在服务器上,以http协议打开,我们打开本地开发服务器,就可以发请求了

报错可能出现版本冲突,我的版本

{
    
    
  "webpack": "^4.25.1",
  "webpack-cli": "^3.1.2",
  "webpack-dev-server": "^3.1.10"
}

devServer.proxy

devServer.proxy 文档

vue react脚手架都以此实现

使用后端在 localhost:3000 上,可以使用它来启用代理:

module.exports = {
    
    
  //...
  devServer: {
    
    
    proxy: {
    
    
      '/api': 'http://localhost:3000'
    }
  }
};

现在,对 /api/users 的请求会将请求代理到 http://localhost:3000/api/users

如果不希望传递/api,则需要重写路径:

module.exports = {
    
    
  //...
  devServer: {
    
    
    proxy: {
    
    
      '/api': {
    
    
        target: 'http://localhost:3000',
        pathRewrite: {
    
    '^/api' : ''}
      }
    }
  }
};

阅读:开发环境

使用时,并没有dist目录,而是放到内存中,提高效率!

8.热模块替换 Hot Module Replacement

场景:我们修改css只会替换css修改的内容,方便调试

const webpack = require('webpack');
// 配置
devServer: {
    
    
  contentBase: './dist',
  hot: true,
  hotOnly: true
}

plugins: [
  new webpack.HotModuleReplacementPlugin()
]

js手动HMR,accept方法

if (module.hot) {
    
    
  module.hot.accept('./number', () => {
    
    
    document.body.removeChild(document.getElementById('number'));
    number();
  });
}

9.使用babel处理es6语法

babel-loader是webpack loader在打包过程中处理

@babel/core是babel核心库

npm install --save-dev babel-loader @babel/core
npm install @babel/preset-env --save-dev

添加webpack配置

module: {
    
    
  rules: [
    {
    
    
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
    
    
        loader: 'babel-loader',
        options: {
    
    
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
},

到此,我们只能处理部分es6语法。但是Promise 数组的 map方法等都不能处理,我们还需要**@babel/polyfill**

通过 Polyfill 方式在目标环境中添加缺失的特性 (通过 @babel/polyfill 模块)

npm install --save @babel/polyfill

在index.js中引入

import '@babel/polyfill';

useBuiltIns配置低版本的特性按需引入

target设置目标浏览器,判断是否需要引入低版本不支持的特性,从而减少体积

loader: 'babel-loader',
options: {
    
    
  presets: [
    [
      '@babel/preset-env',
      {
    
    
        useBuiltIns: 'usage',
        targets: {
    
    
          edge: '17',
	      firefox: '60',
	      chrome: '67',
	      safari: '11.1'
	    }
      }
    ]
  ]
}

猜你喜欢

转载自blog.csdn.net/weixin_43792004/article/details/112621806