webpack4

webpack 其实就是一个 JavaScript 应用程序的静态模块打包器。

webpack 有什么作用?

模块化打包:webpack 会将项目的资源文件当成一个一个模块,模块之间会有依赖关系。webpack 将会对这些有依赖关系的文件进行处理,让浏览器能够识别,最后将应用程序需要的每个模块打包成一个或者多个 bundle。

官方中文文档:https://www.webpackjs.com/concepts/

1. 讲解 webpack 开发环境的搭建,打包模式和效果

1)安装 node

node 官网地址:https://nodejs.org/zh-cn/

安装完后,可以通过命令行输入:node -v 查看 node 版本信息

通过命令行输入:npm -v 查看 npm 版本信息

2)创建 package.json 文件

进入到项目的根目录,输入命令:npm init,一系列的提示,如果不需要直接回车

 最终会在根目录下生成 package.json 文件

 

3)安装webpack

本地安装:(推荐)

npm install --save-dev webpack
npm install --save-dev webpack-cli

全局安装:

npm install --global webpack webpack-cli

这里我选择本地安装,还是进入到项目根目录,输入命令:npm install webpack webpack-cli --save-dev

4)打包

默认 entry 入口 src/index.js

默认 output 出口 dist/main.js

入口和出口都是可以设置的,后面会讲,这里先演示效果,在项目中新建目录和文件

webpack有两种打包模式:webpack --mode development 和 webpack --mode production

我们先设置好这两个打包命令

设置好后在命令行程序中运行 npm run dev 或者 npm run prod 来进行打包。

webpack --mode development 打包模式下的打包效果如下图所示:

webpack --mode production 打包模式下的打包效果如下图所示:

2. webpack 核心配置 config 文件的初使用

1)新建一个 webpack.config.js

2)配置入口 entry(所需打包的文件路径)

3)配置出口 output

(1)path 指文件打包后的存放路径

(2)path.resolve() 方法将路径或路径片段的序列处理成绝对路径

(3)__dirname 表示当前文件所在的目录的绝对路径

(4)filename 是打包后文件的名称

命令行程序运行 npm run dev 或者 npm run prod

 

const path = require('path');

module.exports = {
    entry:'./public/index.js',
    output:{
        path:path.resolve(__dirname,'build'),
        filename:'build.js'
    }
}

3. 讲解入口和出口的多文件用法

入口 entry

  单入口

    单文件
    例如: entry:'./src/index.js'

    多文件

    在你想要多个依赖文件一起注入,并且将它们的依赖导向到一个“chunk”时,传入数组的方式就很有用。
    例如:entry:['./src/index.js','./src/index2.js',...]

  多入口
  例如:

  entry:{
    pageOne:'./src/pageOne/index.js',
    pageTwo:'./src/pageTwo/index.js',
    pageThree:'./src/pageThree/index.js'
  }

出口 output

  单出口

  output:{
    path:path.resolve(__dirname,'build'),
    filename:'build.js'
  }

  多出口(需要和多入口搭配使用)

  output:{
    path:path.resolve(__dirname,'build'),
    filename:'[name].js'
  }

4. 讲解 webpack 如何配置本地服务器

webpack-dev-server 是 webpack 官方提供的一个小型 Express 服务器。使用它可以为 webpack 打包生成的资源文件提供 web 服务。

webpack-dev-server 主要提供两个功能:

(1)为静态文件提供服务

(2)自动刷新和热替换(HMR)

1)安装 webpack-dev-server

npm install --save-dev webpack-dev-server

 

2)配置 webpack.config.js 文件

const path = require('path');

module.exports = {
    entry:'./public/index.js',
    output:{
        path:path.resolve(__dirname,'build'),
        filename:'build.js'
    },
    devServer:{
        contentBase:'./build',    //设置服务器访问的基本目录
        host:'localhost',    //服务器的ip地址
        port:'8080',    //端口
        open:true    //自动打开页面
    }
}

3)配置 package.json

"start": "webpack-dev-server --mode development"

4)在 build 文件夹下新建 index.html 文件,在 html 中引入 bundle.js

 

5)在命令行程序运行 npm run start

6)自动弹出页面,控制台有输出信息

5. 讲解 css 加载器的使用方式

1)了解 loader

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。

2)安装loader

安装 style-loader 和 css-loader

下载:npm install style-loader css-loader --save-dev

3)配置 loader

在 webpack.config.js 文件里配置 module 中的 rules

在 webpack 的配置中 loader 有两个目标:

test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
use 属性,表示进行转换时,应该使用哪个 loader。

代码:

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

4)创建 index.css 文件并 import 进 index.js 文件中

6. 讲解 webpack 编译 less 和 sass 的方式

安装 less-loader 和 less
下载:npm install less-loader less --save-dev

安装 sass-loader 和 node-sass
下载:npm install sass-loader node-sass --save-dev

配置和上面一样,使用对应的 loader 就可以了

7. 使用 PostCSS 自动添加 css3 浏览器前缀

处理效果

编译为

1)安装 postcss-loader 和 autoprefixer

下载:npm install  postcss-loader autoprefixer --save-dev

2)配置 loader(需要和 autoprefixer 一起用)

const path = require('path');

module.exports = {
    entry:'./public/index.js',
    output:{
        path:path.resolve(__dirname,'build'),
        filename:'build.js'
    },
    devServer:{
        contentBase:'./build',    //设置服务器访问的基本目录
        host:'localhost',    //服务器的ip地址
        port:'8080',    //端口
        open:true    //自动打开页面
    },
    module:{
        rules:[
            {
                test:/.css$/,
                use:['style-loader','css-loader',{
                    loader:'postcss-loader',
                    options:{
                        plugins:[
                            require("autoprefixer")({
                                overrideBrowserslist: [
                                    'ie >= 8',//ie版本大于等于ie8
                                    'Firefox >= 20',//火狐浏览器大于20版本
                                    'Safari >= 5',//safari大于5版本
                                    'Android >= 4',//版本大于Android4
                                    'Ios >= 6',//版本大于ios6
                                    'last 4 version'//浏览器最新的四个版本
                                ]
                            })
                        ]
                    }
                }]
            }
        ]
    }
}

在低版本中可以使用 browsers,如果报了这样的错误,就需要使用 overrideBrowserslist 替换掉 browsers 就可以了。

 

 或者在 package.json 里加上设置:

{
  "name": "webpackdemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack --mode development",
    "prod": "webpack --mode production",
    "start": "webpack-dev-server --mode development"
  },
  "author": "jwen",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^9.7.2",
    "css-loader": "^3.2.0",
    "less": "^3.10.3",
    "less-loader": "^5.0.0",
    "postcss-loader": "^3.0.0",
    "style-loader": "^1.0.0",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.9.0"
  },
  "browserslist": [
      "ie >= 8",
      "Firefox >= 20",
      "Safari >= 5",
      "Android >= 4",
      "Ios >= 6",
      "last 4 version"
  ]
}

这样一来 webpack.config.js 就不需要设置了

8.讲解使用 file-loader 处理图片加载

1)下载安装 file-loader

npm install file-loader --save-dev 

2)配置config文件

选项配置

配置options:

name:为你的文件配置自定义文件名模板(默认值[hash].[ext])

context:配置自定义文件的上下文,默认为 webpack.config.js

publicPath:为你的文件配置自定义 public 发布目录

outputPath:为你的文件配置自定义 output 输出目录

[ext]:资源扩展名

[name]:资源的基本名称

[path]:资源相对于 context的路径

[hash]:内容的哈希值

9.讲解使用 file-loader 处理字体文件

1)下载字体文件,以 bootstrap 字体文件为例子

Boostrap字体文件下载地址:https://v3.bootcss.com/getting-started/

2)在 index.js 中引入bootstrap.css,在 html 中使用 bootstrap 字体图标

 

 

配置config文件

{
  test:/.(eot|svg|ttf|woff|woff2)$/,
  use:[{
    loader:'file-loader',
    options:{
      outputPath:'./fonts'
    }
  }]
}

10.讲解使用 file-loader 处理第三方js库

以 jquery 库为例子

第一种方法:

1)本地导入

2)编写配置文件:

webpack.ProvidePlugin 参数是键值对形式,键就是我们项目中使用的变量名,值就是键所指向的库。webpack.ProvidePlugin 会先从 npm 安装的包中查找是否有符合的库。

如果 webpack 配置了 resolve.alias 选项(理解成“别名”),那么 webpack.ProvidePlugin 就会顺着设置的路径一直找下去

使用 webpack.ProvidePlugin 前需要引入 webpack

const path = require('path');
const webpack = require('webpack');

module.exports = {
    entry:'./public/index.js',
    output:{
        path:path.resolve(__dirname,'build'),
        filename:'build.js'
    },
    devServer:{
        contentBase:'./build',    //设置服务器访问的基本目录
        host:'localhost',    //服务器的ip地址
        port:'8080',    //端口
        open:true    //自动打开页面
    },
    module:{
        rules:[
            {
                test:/.css$/,
                use:['style-loader','css-loader',{
                    loader:'postcss-loader',
                    options:{
                        plugins:[
                            require("autoprefixer")
                        ]
                    }
                }]
            },
            {
                test:/.(eot|svg|ttf|woff|woff2)$/,
                use:[{
                    loader:'file-loader',
                    options:{
                        outputPath:'./fonts'
                    }
                }]
            }
        ]
    },
    resolve:{
        alias:{
            jQuery:path.resolve(__dirname,'public/js/jquery.js')
        }
    },
    plugins:[
        new webpack.ProvidePlugin({
          jQuery: 'jQuery'//绿色的表示js中使用的变量名,这个可以随便起,比如这里起名:haha,那么在下面的截图中就可以使用haha
        })
    ]
}

第二种方法:

1)npm 安装 jquery 库:npm install jquery --save-dev

2)直接在 js 里 import 引入:import $ from 'jquery'

11. 使用 babel-loader 编译 ES6 语法

目前,ES6(ES2015)这样的语法已经得到很大规模的应用,它具有更加简洁、功能更加强大的特点,实际项目中很可能会使用采用了ES6语法的模块,但浏览器对于ES6语法的支持并不完善。为了实现兼容,就需要使用转换工具对ES6语法转换为ES5语法,babel就是最常用的一个工具

babel 转化语法所需依赖项:

babel-loader: 负责 es6 语法转化

babel-core: babel 核心包

babel-preset-env:告诉 babel 使用哪种转码规则进行文件处理

1)安装依赖:npm install babel-loader @babel/core @babel/preset-env --save-dev

2)配置config文件

{
    test:/.js$/,
    exclude:/node_modules/,
    use:'babel-loader'
}

exclude表示不在指定目录查找相关文件

3)根目录新建 .babelrc 文件配置转换规则

{
    "presets":["@babel/preset-env"]
}

另一种规则配置(不需要建 .babelrc 文件,直接在 webpack.config.js 里配置)

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

12. 讲解如何使用插件根据模板自动生成html文件并关联相关文件

HtmlWebpackPlugin 会自动为你生成一个 HTML 文件,根据指定的 index.html 模板生成对应的 html 文件。

1)安装依赖:npm install html-webpack-plugin --save-dev

2)配置 config 文件

const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins:[
  new HtmlWebpackPlugin({
    template:'./public/index.html',
    filename:'webpack.html',
    minify:{
      minimize:true,
      removeAttributeQuotes:true,
      removeComments:true,
      minifyCSS:true,
      minifyJS:true,
      removeEmptyElements:true,
      collapseWhitespace:true  
    },
    hash:true
  })
]

13. 讲解如何从打包后的chunk文件中提取分离出css

将所有的入口 chunk(entry chunks)中引用的 css,移动到独立分离的 CSS 文件

方法一:使用 ExtractTextPlugin 插件

1)下载插件:npm install --save-dev extract-text-webpack-plugin@next

2)配置config文件

const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("./css/styles.css"),
  ]
}

方法二:使用 mini-css-extract-plugin 插件

1)下载插件:npm install --save-dev mini-css-extract-plugin

2)配置 config 文件

const MiniCssPlugin = require("mini-css-extract-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /.css$/,
        use: [MiniCssPlugin.loader,'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssPlugin({
            filename:'./css/styles.css'
    })
  ]
}

14. 讲解使用插件压缩css及优化css结构

1)下载插件:npm install --save-dev optimize-css-assets-webpack-plugin

2)配置 config 文件

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

module.exports = {
  plugins: [
    new OptimizeCssAssetsPlugin({
        assetNameRegExp:/.css$/g,
        cssProcessor:require("cssnano"),
        cssProcessorPluginOptions:{
            preset:['default',{discardComments:{removeAll:true}}]
        },
        canPrint:true
    })
  ]
}

assetNameRegExp:正则表达式,用于匹配需要优化或者压缩的资源名。默认值是 /.css$/g

cssProcessor:用于压缩和优化CSS 的处理器,默认是 cssnano.

cssProcessorPluginOptions:传递给cssProcessor的插件选项,默认为{}

canPrint:表示插件能够在console中打印信息,默认值是true

discardComments:去除注释

15. 讲解如何拷贝静态资源文件到打包后的目录

1)下载插件:npm install --save-dev copy-webpack-plugin

2)配置 config 文件

const CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = {
  plugins: [
    new CopyWebpackPlugin([
        {
            from:__dirname+'/public/assets',
            to:__dirname+'/build/assets'
        }
    ])
  ]
}

16. 讲解如何清除之前打包的旧文件

当我们修改带hash的文件并进行打包时,每打包一次就会生成一个新的文件,而旧的文件并没有删除。为了解决这种情况,我们可以使用clean-webpack-plugin在打包之前将文件先清除,之后再打包出最新的文件

1)下载插件:npm install --save-dev clean-webpack-plugin

2)配置 config 文件

const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  plugins: [
    new CleanWebpackPlugin()
  ]
}

插件地址:https://www.npmjs.com/package/clean-webpack-plugin

17. 讲解 webpack 如何处理 html 中引入的图片

未使用 loader 时,会出现路径错误,图片不显示的情况

1)下载 loader:npm install --save-dev html-loader

2)配置 config 文件

{
  test: /.(png|jpg|jpeg|gif)$/,
  use: 'file-loader'
},
{
  test: /.html$/,
  use: {
    loader: 'html-loader',
    options: {
      minimize: true
    }
  }
}

18. 讲解 sourcemap 的作用和调试方式

sourcemap 是为了解决实际运行代码(打包后的)出现问题时无法定位到开发环境中的源代码的问题。

对于 js 调试来说,只需要设置 devtool,对于 css 调试,需要设置 css-loader 的可选项。

19. webpack 开发调试必备功能之模块热替换 HMR

模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面时丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。

配置config文件

Plugin设置

NamedModulesPlugin:当开启 HMR 的时候使用该插件会显示模块的相对路径

其他配置

devServer中加入hotOnly表示只有热更新,不会自动刷新页面

修改js文件时代码不会自动热更新,需加入以下代码可以告诉 webpack 接受更新的模块

20. 讲解如何区分生产环境和开发环境的配置

开发环境和生产环境的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载或热模块替换能力和 localhost server。 而在生产环境中,我们的目标则转向于关注更小的 bundle,以及资源的优化,以改善加载时间。所以我们通常建议为每个环境编写彼此独立的 webpack 配置。

1)安装插件:npm install --save-dev webpack-merge

2)拆分文件

在这里我们可以将 webpack.config.js 拆分为三个文件,分别是 webpack.common.conf.js、webpack.dev.conf.js 和 webpack.prod.conf.js。

 

webpack.common.conf.js 是放一些我们公用的配置,比如入口entry、出口output、常用loader以及插件等。

webpack.dev.conf.js 是在开发环境上的配置,比如devServer配置、模块热替换等方便开发的配置

webpack.prod.conf.js 是在生产环境上的配置,比如提取分离css、压缩css和js等

webpack.common.conf.js

 

 webpack.dev.conf.js

 

 webpack.prod.conf.js

 

3)修改 package.json 文件中的script

--config可以指定使用的配置文件          

  

   

原文地址:https://www.cnblogs.com/jwen1994/p/11919352.html