webpack

2019-06-13  本文已影响0人  致自己_cb38

一、 初试牛刀

1.简介

1) 为什么要使用webpack

现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法

Ø 模块化,让我们可以把复杂的程序细化为小的文件

Ø 类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能转换为JavaScript文件使浏览器可以识别

Ø Scss,less等CSS预处理器

Ø ES6 babel

这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就为WebPack类的工具的出现提供了需求

2) 什么是webpack

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。将多个文件打包成一个文件或者对项目进行优化(打包,转化和优化)。

image.png

2.起步

1) 安装

参考文献:
https://blog.csdn.net/xiaolinlife/article/details/85058160
https://www.cnblogs.com/aizai846/p/11497508.html

前提条件:在开始之前,请确保安装了 Node.js 的最新版本。使用 Node.js 最新的长期支持版本(LTS - Long Term Support),是理想的起步。使用旧版本,你可能遇到各种问题,因为它们可能缺少 webpack 功能以及/或者缺少相关 package 包。

要安装最新版本或特定版本,请运行以下命令之一

npm install --save-dev webpack或者npm i webpack --save-dev

npm install --save-dev webpack@<version>

如果你使用 webpack 4+ 版本,你还需要安装 CLI

npm install --save-dev webpack-cli或者npm i webpack-cli -D

webpack与webpack-cli两者结合简写
npm i webpack webpack-cli -D

输入如下命令,将在项目目录中自动生成package.json文件

npm init -y //不加-y为手动生成

补充:

npm install name -save 简写(npm install name -S) 自动把模块和版本号添加到dependencies

npm install name -save-dev 简写(npm install name -D) 自动把模块和版本号添加到devdependencies

-D后,安装包会在package中的 devDependencies对象中,简称dev,dev是在开发环境中要用到的

-S后,安装包会在package中的 dependencies 对象中,简称dep,dep是在生产环境中要用到的

举个例子:
构建工具:gulp和webpack是用来压缩代码,打包等需要的工具,程序实际运行的时候并不需要,就要放在dev中所以要用 -D
项目插件:例如element ui、echarts这种插件要在运行中使用的,就要放在dep中所以就用 -S

对于大多数项目,我们建议本地安装。这可以使我们在引入破坏式变更(breaking change)的依赖时,更容易分别升级项目。通常,webpack 通过运行一个或多个 npm scripts,会在本地 node_modules 目录中查找安装的 webpack

"scripts": {
    "start": "webpack --config webpack.config.js"
}

当你在本地安装 webpack 后,你能够从 node_modules/.bin/webpack 访问它的 bin 版本

2) 简单使用

image.png
const path = require('path')
module.exports = {
    mode: 'production',
    entry:'./src/js/index.js',
    output:{
        path:path.join(__dirname,'dist'),
        filename:"bundle.js"
    },
}

3.初识webpack

1) webpack打包一个文件

webpack  ./src/index.js --output dist/bundle.js

2) webpack配置文件

module.exports= {
    //入口
    entry:{},
    //出口
    output:{},
    //loader加载器
    module:{
        rules: [
            { test: /\.txt$/, use: 'raw-loader' }
        ]
    },
    //插件
    plugins:{},
    //开发服务器
    devServer:{}    
}

4) webpack的配置文件名

默认的是webpack.config.js。但是不一定必须是这个

webpack --config config_file_name

5) 配置npm 命令

在package.json文件中具有一个scripts的设置项中可以设置npm的命令

例如:npm run build

“scripts”:{
    “build”:“webpack --config config_file_name”
 }

 "scripts": {
    "build": "./node_modules/.bin/webpack --config webpack.config.js"
  }

// webpack4.x
“scripts”:{
    “build”:“webpack”
 }

注意:编译后的文件在“/”目录下,在html里引入时路径应为"/indexbundle.js"

6) 模式

webpack  --mode develepment
webpack  --mode production

 "scripts": {
    "build": "./node_modules/.bin/webpack --config webpack.config.js --mode develepment"
  }

4.配置文件基本组成结构

1) 入口

入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

可以通过在 webpack 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src。

2) 出口

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程:

3) 模式

通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

4) loader

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

本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

在更高层面,在 webpack 的配置中 loader 有两个目标:

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

use 属性,表示进行转换时,应该使用哪个 loader。

5) 插件plugins

loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

二、 webpack深入

1.入口

1) 多入口单出口

entry:[‘i.js’,’2.js’]

2) 多入口多出口

entry:{
     name1: ‘1.js’,
     name2: ’2.js’
},
output:{
   path:path.join(__dirname,'dist/'),
   filename: ‘[name]bundle.js’
}

2.出口

注意:

1、出口的默认路径

2、出口是绝对路径

3、出口的默认文件名与main的关系

3.html-webpack-plugin插件

用于编译 Webpack 项目中的 html 类型的文件,如果直接将 html 文件置于 ./src 目录中,用 Webpack 打包时是不会编译到生产环境中的。因为 Webpack 编译任何文件都需要基于配置文件先行配置的。

插件 html-webpack-plugin 的详解

1) 安装

npm i html-webpack-plugin -D

2) 引入

const HtmlWebpackPlugin = require(‘html-webpack-plugin’);

3) 使用

plugins:[
   new  HtmlWebpackPlugin({
     title:’’,//页面标题
     template:’./src/index.html’ //指定你生成的文件所依赖哪一个html文件模板,模板类型可以是html、jade、ejs等
   });
]

title的使用
<%=htmlWebpackPlugin.options.title%>

注意:依赖 webpack 与webpack-cli

4) 消除缓存

plugins:[
   new  HtmlWebpackPlugin({
     hash:true,
     title:’’,//页面标题
     template:’./src/index.html’ //模板文件
  }),
]

5) 压缩输出

plugins:[
    new htmlWebpackPlugin({
        hash:true,
        minify:{
            collapseWhitespace:true, //去除空格
            removeComments //去除注释
            minifyCSS
            minifyJS
        },
        template:'./src/index.html',        
    }),
]

minify 的配置:https://blog.csdn.net/lqlqlq007/article/details/84103859

6) 生成多个页面

plugins:[
        new htmlWebpackPlugin({
            hash:true,
            minfy:{
                collapaseWhitespace:true,
            },
            template:'./src/index.html',
            filename: file1
        }),
        new htmlWebpackPlugin({
            hash:true,
            minfy:{
                collapaseWhitespace:true,
            },
            template:'./src/nav.html',
            filename: file2
        })
]

7)多页面分离引入

入口文件
entry:{
        index:'./src/index.js',
        index2:'./src/index2.js'
    },
// 出口文件
output:{
    path:path.join(__dirname,'dist/'),
    filename:'[name]bundle.js'
},

插件配置
new htmlWebpackPlugin({
    hash:true,
    chunks:[“name1”,”name2”], // chunks主要用于多入口文件,当你有多个入口文件,那就回编译后生成多个打包后的文件,那么chunks 就能选择你要使用那些js文件
    minfy:{
        collapaseWhitespace:true,
    },
    template:'./src/index.html',
    filename: file1
}),
new htmlWebpackPlugin({
    hash:true,
    chunks:[name2],
    minfy:{
        collapaseWhitespace:true,
    },
    template:'./src/index.html',
    filename: file2
})

4.clean-webpack-plugin

1) 下载

npm i clean-webpack-plugin -D

2) 引入

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

3) 使用

在html-webpack-plugin插件使用之前去除已经产生的垃圾文件

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
    /*
    入口 多入口单出口使用数组 ['./public/src/js/index.js','./public/src/js/reindex.js',]
    entry:'./src/js/index.js',
    */ 
    /*多入口多出口*/
    entry:{
        index:'./src/js/index.js',
        reindex:'./src/js/reindex.js',
    },
    
    // 出口 默认的出口目录是dist
    output:{
        path:path.join(__dirname,'dist/'),
        // filename:'bundle.js',
        filename:'[name]bundle.js'
    },
    // 打包模式
    mode:'development',
    // 自动引入插件
    plugins:[
        new CleanWebpackPlugin(), // 删除文件 保留新文件
        new HtmlWebpackPlugin({
            hash:true, // 清除缓存
            chunks:['index','reindex'], // 在压缩后的html里引入的bundle里的一部分压缩代码
            filename:'index.html', // ../html/index.html
            title:"lalala",
            template:'./index.html',
            minify:{
                collapseWhitespace:true // 去除空格
            }
        }),
        new HtmlWebpackPlugin({
            hash:true, // 清除缓存
            chunks:['reindex'],
            template:'./reindex.html',
            filename:'reindex.html'
        }),
    ]
}

5.webpack-devserver

一个轻量级的服务器,修改文件源码后,自动刷新页面将修改同步到页面上

1) 下载

npm i webpack-devserver webpack-dev-server -D

2) 配置

devServer:{
      host:localhost,
      port:8090,
      contentBase:path.join(__dirname,’dist’)
}

3) 配置启动

npm run dev

“scripts”:{
    “dev”:“webpack-dev-server --config config_file_name”
 }

scripts:{
   “dev”:”webpack-dev-server --config webpack.config.js”
}

// webpack4.x
scripts:{
   “dev”:”webpack-dev-server”
}

4) 自动打开

devServer:{
      host:localhost,
      port:8090,
      contentBase:path.join(__dirname,’dist’),
      open:true
}

5) 热更新

const webpack = require(“webpack”);
devServer:{
      host:localhost,
      port:8090,
      contentBase:path.join(__dirname,’dist’),
      open:true,
      hot:true
},
plugins:[
     new webpack.HotModuleReplacementPlugin()
]
image.png

三、 loader

加载器,转化器

1.打包css

1) 安装

css-loader

style-loader

npm i css-loader style-loader -D

2) 配置

module:{
    rules:[
        {
            test:/\.css$/, //匹配的文件类型
            use:['style-loader','css-loader'] //对应要调用的loader
        }
    ]
}

关于使用loader的三种写法:

use:['style-loader','css-loader']
loader:['style-loader','css-loader']
use:[
     {loader:style-loader },
     {loader:css-loader }
]

2.压缩代码(之前)uglifyjs

1) 下载

npm i uglifyjs-webpack-plugin -D

2) 引入

const uglify = require(‘uglifyjs-webpack-plugin’)

3) 使用

new uglify()

3.图片

1) 下载

npm i file-loader url-loader -D

2) 使用

{
  test:/\.(png|jpg|gif|jpeg)/,
  use:['url-loader']
}

3) base64转码

use:[
  {
    loader:’url-loader’,
    options:{
      limit:50000 //指定图片大小,小于limit转为base64
      outputPath: 图片放置目录
      publicPath: 解决图片路径
    }
  }
]

4.分离css代码 1(已被弃用)

1) 安装

npm i extract-text-webpack-plugin -D

2) 引入

const extract = require('extract-text-webpack-plugin');

3) 使用

在plugins中添加:
new extract('css/index.css'),

在use中修改
use:extract.extract({
  use:'css-loader',
  fallback:'style-loader'
})

4) 注意:

npm run build 报错

image.png
npm i extract-text-webpack-plugin@next -D    为4.X

npm i extract-text-webpack-plugin -D   为3.x

5.分离css 2

安装:

npm i mini-css-extract-plugin -D

使用:

// 在js中引入sass
require('../css/index.css')

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // you can specify a publicPath here
              // by default it uses publicPath in webpackOptions.output
              publicPath: '',
              // hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

6.打包less

安装:

npm i less less-loader -D

使用:

// 在js中引入less
require('../less/index.less')

// 在config里进行配置
new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
}),
{
    test:/\.less$/,
    // use:['style-loader','css-loader','less-loader']
   // 分离
    use:[
        {
            loader:MiniCssExtractPlugin.loader,
            options:{
                publicPath:'',
            }   
        },
        'css-loader','less-loader'              
    ]
}

7.打包sass

安装:

npm i node-sass sass-loader -D

使用:

// 在js中引入sass
require('../sass/index.scss')

// 在config里进行配置
new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
}),
{
    test:/\.(sass|scss)$/,
    // use:['style-loader','css-loader','sass-loader']
   // 分离
    use:[
        {
            loader:MiniCssExtractPlugin.loader,
            options:{
                publicPath:'',
            }   
        },
        'css-loader','sass-loader'              
    ]
}

8.postcss添加css前缀

1) 下载

npm i postcss-loader autofrefixer -D

2) 配置单独的配置文件 postcss.config.js

module.exports={
  plugins:[
    require(‘autoprefixer’)
  ]
}

3) 配置loader

use:[‘css-loader',‘postcss-loader’]

9.消除冗余

将项目中没有用到的css代码或js代码过滤掉(注释掉),不将其打包到文件中

1) 下载

npm i purifycss-webpack purify-css -D

npm i glob -D

2) 引入

const glob = require('glob');
const purify = require(‘purifycss-webpack’)

3) 使用

需要使用到一个扫描路径的包 glob

new purify({
   paths:glob.sync(path.join(__dirname,’./src/*.html’))
})

10.调试

4.x

--mode production

3.x

devtool:’source-map’

11.babel

将js由ES5转换成ES6的格式

官方文档
webpack编译ES6,ES7,babel-loader的使用

1) 安装

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

2) 使用

{
      test: /\.(js|jsx)/,
      exclude: /(node_modules|bower_components)/,
      use:[ {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }]
}

12.react (jsx)

npm i babel-preset-react -D

npm i react react-dom -D

四、 杂项

1.模块化的使用

遵循node模块的引入与导出

2.在webpack中使用json

之前需要json-loader。但是4.x默认可以引入json。

const name = require(‘xxx.json’)

3.静态资源拷贝(图片、文字、js等)

1) 下载

npm i copy-webpack-plugin -D

2) 引入

const CopyPlugin = require('copy-webpack-plugin');

3) 使用

new CopyWebpackPlugin([{
   from: path.join(__dirname,’src/image’),
   to:path.join(__dirname,’dist/image’)
}])

4.使用第三方库

1) 下载

2) 引入

3) 使用

4) 第二种方式 (推介)

只有在内部使用到模块的时候才会打包

new webpack.providePlugin{{
    $:’jquery’,
    lodash: ‘lodash’
}}

5) 提取第三方库

image.png

5.简单的打包发布

 "scripts": {
    "build": "webpack -p"
  }
上一篇下一篇

猜你喜欢

热点阅读