习惯用脚手架的你, 了解Webpack这些知识点吗?

大概准备春招两个月了, 也没找到坑位埋自己, 来看看webpack

webpack

官网: www.webpackjs.com

对于前端的大兄弟来说, 每天在前端摸爬滚打, 各方征战, 那对于webpack肯定再熟悉不过了

所以说这篇文章适合给像我们这样的后端的同胞看着玩,(一说前端不是想用BootStrap就想用其他前端框架的UI组件库, 要不就是vue的脚手架) , 那对于浪迹各大vue react组件库的你, 对于喜欢用脚手架构建项目的你, 对于喜欢一键打包项目的你, 真的了解webpack各种目录和默认配置吗?

webpack的核心概念:

  • 入口: 从哪里开始打包
  • 出口: 打包的结果输出到哪里去
  • loader: 我们通过npm给webpack安装上不同的loader, webpack就能处理不同格式的文件, 用于处理图片等静态资源的loader, 处理css的loader, 处理less的loader, 用于适配各种浏览器的loader等等
  • 插件: 作用于整个打包过程, 比如用于本件拷贝的插件, 用于生成html的插件, 用于处理css的插件

搭建一个空的项目

通过这个小案例你将了解:

  • 局部安装webpack-cli的命令是什么 ?
  • 如何在新项目中使用局部安装的webpack ?
  • webpack的默认启动目录, 启动文件在哪里 ? 叫什么 ?
  • 什么是mode? (development production)
  • 有哪些build mode , 这些mode有何区别 ?

继续:

命令: npm init 创建一个空项目

执行完成后, 会为我们生成一个packetage.json文件

然后安装webpack 包管理工具命令: npm i webpack-cli -D

注意点:上面的安装命令是局部安装命令,  如果我们进入这个项目中, 使用npm run build命令尝试将这个项目打包时, 会报错 说 missing script : build

https://img2018.cnblogs.com/blog/1496926/202002/1496926-20200217120818449-1264723973.png

解决方法: 在package.json的script部分中加入下面的配置 后, 再使用 npm run build 命令时, 会自动使用我们在局部安装的这个命令

https://img2018.cnblogs.com/blog/1496926/202002/1496926-20200217120818212-77114974.png

--mode 指定在什么环境下打包, 上面的 production 就是说打包后在生产环境下使用, 和development最直接的不同点就是 前者会将main.js 压缩

继续执行npm run build 命令: 会遇到新的错误, 说解析不到 src目录, 原因是webpack找到不到入口目录https://img2018.cnblogs.com/blog/1496926/202002/1496926-20200217120817923-192514119.png

默认的, webpack的入口会去找 src/index.js

我们在根目录下将这个目录创建出来, 再次执行npm run build 即可打包成功, 打包的结果: /dist/main.js , 会将项目中依赖的js文件, 打包成一个js文件

npm run xxx ,命令中的xxx就是上图中的srcipt中定义的 比如npm run dev , npm run build , npm run start , npm run test

webpack的配置文件

看完这本小节你将了解:

  • webpack默认的配置文件叫什么 ?
  • webpack默认的配置文件在哪里 ?
  • 如何修改webpack默认配置文件所在的路径和名称 ?
  • webpack的入口js文件可以修改吗? 如何修改 ?
  • webpack的配置文件中output目录及文件可以修改吗? 如何修改 ?
  • output输出的目标文件默认叫什么名? 可以修改吗?
  • webpack有哪些hash函数可以使用 ?

ok, 继续:

  • 有哪些默认的配置?

webpack.config.js, 默认的webpack会去根目录中寻找他, (如过我们把它放在自定义的目录中, webpack是找不到它的)

但是可以在 package.json中去修改这个默认的配置, 如下: 添加--config 参数

  • 能添加哪些自定义的配置?

webpack.config.js 配置文件的作用的对外暴露node.js的配置脚本, 看下图, 可以知道, webpack.config.js中对应的就是webpack对应的各个模块的

https://img2018.cnblogs.com/blog/1496926/202002/1496926-20200217120817282-974148143.png

参照这个连接: https://www.webpackjs.com/concepts/configuration/

用大白话说, webpack.config.js 可以告诉webpack打包的mode, 是否需要压缩, 入口js文件在哪里, 打包结果输出到什么目录, 输出结果叫什么, 等等

var path = require('path');
module.exports = {
    mode: 'development', // 指定打包后在什么环境下使用
    entry: './src/index.js', // 指定入口js文件, todo 可以在这里修改入口js文件
    output: {
        path: path.resolve(__dirname, 'dist'), // 打包后的文件所在的目录名
        //filename: 'foo.bundle.js' // 打包后生成的文件名, 默认是main.js

        // hash值是通过入口目录中的入口js算出来的, 一旦js改变, 每次build的结果的hash值
        //filename: '[name].[hash].js' // 生成的文件名: main.e9bsajdoahsds.js
        //filename: '[name].[hash:6].js' // 生成的文件名: main.6位长度hash值.js
        filename: '[name].[chunkHash:6].js' // 生成的文件名: main.6位长度hash值.js  且共存多个模块时, 只有那个发生变动的入口js对应生成的 output文件名中的js哈希值才会改变

        // 第三种hash contenthash ,是根据文件的内容计算出来的hash
    }
};
  • webpack的三种hash值
    • hash: 它是工程级别的, 即修改工程中任何一个文件, 整个工程的文件缓存都会失效, 打包出来的文件的hash值都会发生改变, 缺点: 如果项目存在多个入口, 势必针对每一个入口js文件都打包出来一个带有hash值的结果文件, 虽然是两个不同的入口, 但是属于一个工程, 所有多个目标文件的hash值都会改变
    • chunkHash: 它解决了hash的缺点带来的不足条件, 还是同一个项目,多个入口js的情况, 使用chunkHash模式, 然后修改一个入口js的内容, 打包出来的结果文件中, 只有被修改了的那个js的hash改变;
    • contentHash: 根据文件的内容计算hash

打包后自动生成html

学完本节你将了解

  1. 如何让webpack打包出一个单页index.html
  2. 如何让webpack基于我们自己提供的html页面生成 index.html

参考链接: https://www.npmjs.com/package/html-webpack-plugin

默认的, webpack会将项目中依赖的js文件打包称一个js文件输出到 / dist / 目录中, 但是不会为我们生成html文件, 这时候我们需要手动的将生成的js文件引入到我们自己的index.html文件中, 这样整挺麻烦的

所有, 一般我们会这么搞, 把自己的index.html文件放在/public/index.html中, 然后安装webpack的插件, 让这个插件替我们完成上面的那个复杂的过程, 如下

安装命令:

npm i --save-dev html-webpack-plugin

参考: webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')
 
module.exports = {
  entry: 'index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'index_bundle.js'
  },
 // 着重看一下这个plugin模块   
 plugins: [
    new HtmlWebpackPlugin(), // Generates default index.html
    new HtmlWebpackPlugin({  // Also generate a test.html
      filename: 'test.html',
      // 允许用户自定义一个html模板, webpack会在这个模板上累加上自己生成的js  
      template: 'src/assets/test.html'
    })
  ]
}

引入CSS

看完本节你将了解:

  1. 两种方式让webpack替我们导入css文件

参考链接: https://www.npmjs.com/package/css-loader

  • 第一种方式:

安装loader插件命令

npm i style-loader -D
npm install --save-dev css-loader

参考配置文件 : 通过一个rules来控制这个过程, 通过正则匹配到css, 然后对这些匹配到的文件使用 style-loader css-loader , 执行的顺序的 后面的css-loader比style-loader先执行

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

通过如下方式将css引入

导入css

此时再执行 npm run build 可以完成构建工作

问题来了, 通过这种方式导入进来的css文件在哪里呢?

通过查看html源码可见, 构建出来的源码被放在head标签中


  • 第二种引入css文件的方式, 将css导入进来, 并提取成一个独立的文件, 并自动插入到html中

参考链接: https://www.npmjs.com/package/mini-css-extract-plugin

安装命令:

npm install --save-dev mini-css-extract-plugin

参考webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 
module.exports = {
  // 在plugins部分new出来
  plugins: [
    new MiniCssExtractPlugin(
  	 {
        filename: '[name].[chunkHash:8].css'
      }
  )],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              esModule: true,
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

这种方式生成结果如下:

很明显: css被添加在head标签中, script添加在index.html末尾

小技巧, 如果想让生成的文件呈现下面的样子:

可以在webpack.config.js文件中, 使用下面的方式为文件命名

new MiniCssExtractPlugin(
            {
                filename: 'css/[name].[chunkHash:8].css'
            }
   )

CSS预处理

参考链接: https://www.npmjs.com/package/less-loader

目的是处理less, 将less转换成css

安装 less 和 less-loader

 npm install less less-loader --save-dev

在webpack.config.js中添加less的解析规则

loader的第二种写法

		{
                test: /\.less$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                   // 'less-loader',
                    {
                        loader: "less-loader",
                        options:{
                            
                        }
                    }
                ],
            }

自动添加CSS前缀

看完本节你将了解

  1. 啥是css3前缀
  2. 为啥要加前缀
  3. 怎么通过webpack添加前缀

**那为啥要添加前缀呢? **

因为在CSS标准未被确定之前, 市面上的不同浏览器使用自己私有的前缀却分不同的CSS样式, 当标准确定之后, 各大浏览器不再使用这些前缀, 目前很多私有的前缀都可以不再写了, 但是为了兼容, 可以仍然使用前缀逐渐过度

常见的浏览器的前缀如:

  1. Chrome谷歌浏览器: -webkit-
  2. Safari苹果浏览器: -webkit-
  3. FireFox 火狐: -moz-
  4. IE: -ms-
  5. Opera 欧朋浏览器: -O-

例:

#example{
    -webkit-outline: none;
    -moz-outline: none;
    -ms-outline: none;
    -o-outline: none;
    -khtml-outline: none;
    outline: none;
}

如何配置webpack, 自动添加浏览器css3前缀

参考链接: https://www.npmjs.com/package/autoprefixer

安装命令:

npm i postcss-loader autoprefixer -D

第二步: 在项目的根目录下创建 postcss.config.js 配置文件

postcss的npm包参考链接: https://www.npmjs.com/package/postcss

 module.exports = {
  plugins: [
      // 他需要下面的插件 autoprefixer
    require('autoprefixer'),
  ]
}

第三步: 在webpack.config.js配置文件中添加指定的postcss-loader, 注意把他的添加顺序, 放在靠前的位置

第四步: 在package.json配置文件中添加 browerslist相关配置, 可以针对不同浏览器做出更详细的配置

参考链接: https://www.npmjs.com/package/browserslist

实例:

 "browserslist": [
    "defaults",
    "not IE 11",
    "not IE_Mob 11",
    "maintained node versions",
  ]

并不是浏览器包含的越多越好, 比如说想用ES5的话, IE的版本至少要大于等于8

处理资源文件

看完本节, 你将了解:

  1. 三种处理资源文件的方式
  • 第一种处理方式 file-loader

使用file-loader处理资源文件, 参考链接 <https://www.npmjs.com/package/file-loader >

安装命令: 

npm install file-loader --save-dev 

参照上面链接中的示例配置, 为webpack.config.js中添加file-loader相关的模块

示例:

  rules: [		     
		  {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options:{
                            // 指定webpack打包后, 输出的路径
                            name: 'static/images/[name].[ext]',
                            // 这个publicPath规定的路径, 就是webpack运行项目后, 所有的资源文件url的最前面的公共部分
                            publicPath: '/',
                        }
                    },
                ],
            }
      ]

注意点: 如果不添加publicPath的话, 将出现下面的问题

  • 第二种处理方式

参考链接: https://www.npmjs.com/package/url-loader

url-loader的优点, 会针对不同图片做不同的压缩

安装命令

npm install url-loader --save-dev

同样是在webpack.config.js中添加配置

   {
                test: /\.(png|jpg|gif)$/i,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            // url-loader和file-loader的工作原理相似, 当资源的大小小于limit指定的值时, 资源将被替换成base64编码的数据植入html或者 css中
                            limit: 80,
                            name: 'static/images/[name].[ext]',
                            // 这个publicPath规定的路径, 就是webpack运行项目后, 所有的资源文件url的最前面的公共部分
                            publicPath: '/',
                        },
                    },
                ],
            }

url-loader的特点如下:

  1. 当资源size < limit值时, 将使用base64对资源进行加密处理
  2. 当资源size > limit值时, 和file-loader相似, 将图片本身输出到指定的目录中
  • 第三种处理方式

比如项目中引用了字体文件, 直接写死在index.html模板中, 而不需要使用file-loader或者url-loader进行压缩之类webpack的处理和生成的操作, 那么可以使用下面的插件, 直接进行文件的copy

参考链接: https://www.npmjs.com/package/copy-webpack-plugin

命令:

npm install url-loader --save-dev

参考webpack.config.js如下:

const CopyPlugin = require('copy-webpack-plugin');
 
module.exports = {
  plugins: [
       new CopyPlugin([
            {   // 将项目根路径下的static目录中的内容, 拷贝到dist/static/images中
                from: path.resolve(process.cwd(),'static/'),
                to: path.resolve(process.cwd(),'dist/static/images中')
            },
        ]),
  ],
};

添加Babel-loader

为什么要使用babel-loader?

我们都是到, 浏览器只认识html css 原生js , 后续js发展的很快, ES5 ES6出世了, 但是不少浏览器根本不支持ES6的语法, 比如 import export 对象/函数 等等

如何使用?

参考链接: https://www.npmjs.com/package/babel-loader

安装命令:

npm install -D babel-loader @babel/core @babel/preset-env webpack

示例:

rules: [
  // the 'transform-runtime' plugin tells Babel to
  // require the runtime instead of inlining it.
  {
    test: /\.m?js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env'],
        plugins: ['@babel/plugin-transform-runtime']
      }
    }
  }
]

webpack让前端项目独立占用一个端口运行

通过这小节你将知道:

  1. webpack 通过什么让前端项目独立运行
  2. 如何安装这个插件
  3. 如何配置进webpack, 让webpack使用它
  4. 在那个配置文件中对devs-server进行更多的配置

参考连接: https://www.npmjs.com/package/webpack-dev-server

安装命令:

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

修改npm的配置文件, 添加dev选项

Snipaste_2020-02-15_11-30-28

这也就是为啥, 通过脚手架构建的开发环境, 能npm run dev 运行起来

并且, 项目运行起来后, 我们做出的任何修改, 都会热加载进来, 时时更新, 无须重启

在webpack.config.js中添加devServer模块

如:

Snipaste_2020-02-15_11-42-46

一般在开发时. 这个配置肯定是需要定制的, 如果在这里模拟前后端联调, 就在这个模块配置mock数据的地址

 devServer: {
   change xxx-api/login => mock/login
    detail: https://cli.vuejs.org/config/#devserver-proxy
  },

或者是真的在前后端联调, 因为端口不同将出现跨域, 在这里配置代理服务器的地址

// 参考: https://www.webpackjs.com/configuration/dev-server/#devserver-proxy
devServer: {
   proxy: 'http://localhost:8089'
},

比如, 自动打开啊等等, 更多的配置 参考链接 https://www.webpackjs.com/configuration/dev-server/

posted @ 2020-02-17 12:17  赐我白日梦  阅读(1156)  评论(1编辑  收藏  举报