JAVASCRIPT
VUE
REACT
NODE
ES6
TYPESCRIPT

关于webpack

2021. 02. 20    

关于Webpack学习

我的博客

webpack安装

1.先初始化一个文件

cd 当前目录
npm init //初始化一下  会产生一个 package.json 文件	
之后提示不用管 //一路回车
直到...
About to write to 目录\package.json:
{
  "name": "...",
  "version": "1.0.0"
  ...
}
Is this ok? (yes) //回车 完成

安装webpack

npm install webpack --save-dev
npm install webpack-cli --save-dev //webpack4.+ 版本需要安装webpack-cli 

mode开发模式

webpack 提供 mode 配置选项,配置 webpack 相应模式的内置优化。

文件:webpack.config.js

module.exports = {
  mode: "production", //产品模式  会压缩和优化
  mode: "development", //开发模式
  mode: "none", // no defaults
}

入口文件

entry 对象是用于 webpack 查找启动并构建 bundle。其上下文是入口文件所处的目录的绝对路径的字符串。

文件:webpack.config.js

module.exports = {
  entry: "./app/entry", // string | object | array
  entry: ["./app/entry1", "./app/entry2"],
  entry: {
    a: "./app/entry-a",
    b: ["./app/entry-b1", "./app/entry-b2"]
  },
}

输出(output)

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。

文件:webpack.config.js

const path = require('path');
module.exports = {
  output: {
    // webpack 如何输出结果的相关选项

    path: path.resolve(__dirname, "dist"), // string
    //__dirname   以当前目录下产生一个 dist
    // 所有输出文件的目标路径
    // 必须是绝对路径(使用 Node.js 的 path 模块)

    filename: "bundle.js", // string
    filename: "[name].js", // 用于多个入口点(entry point)(出口点?)
    filename: "[chunkhash].js", // 用于长效缓存
    // 「入口分块(entry chunk)」的文件名模板(出口分块?)

    publicPath: "/assets/", // string
    publicPath: "",
    publicPath: "https://cdn.example.com/",
    // 输出解析文件的目录,url 相对于 HTML 页面

    library: "MyLibrary", // string,
    // 导出库(exported library)的名称

    libraryTarget: "umd", // 通用模块定义
  }
}

服务配置

开发中希望通过localhost方式访问,或者IP地址来访问

文件:webpack.config.js

//安装webpack内置的开发服务   运行npm install webpack-dev-server --save-dev
npm install webpack-dev-server --save-dev
const path = require('path');
module.exports = {
  devServer: { //开发服务器的配置
    port: 3000, //修改端口号
    progress: true, //内存打包出现进度条
    contentBase: './bulid', //以build 目录作为静态服务
    open: true, //自动打开浏览器
    compress: true,//启用gzip压缩
  },
}

//运行时   npm webpack-dev-server  
//webpack-dev-server 命令也可以在packge.json 文件里面进行配置 

文件:packge.json

{
  "name": "webpack-dev-1",
  ...
    
  "scripts": {
    "build": "webpack --config wepack.config.min.js",
    "dev": "webpack-dev-server"
   },

  "devDependencies": {
    ....
  }
}
//运行时   npm dev  即可 

跨域问题

文件:webpack.config.js

//安装webpack内置的开发服务   运行npm install webpack-dev-server --save-dev
npm install webpack-dev-server --save-dev
const path = require('path');
module.exports = {
  devServer: { //开发服务器的配置
    ...
    proxy:{//解决跨域问题
    	
    	'/api': {
    		target: 'http://localhost:3000',
    		pathRewrite: {'/api': ''}
    	}
    }
  },
}

loader

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

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

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

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

文件:webpack.config.js

//先安装 less-loader 和 style-loader
npm install css-loader style-loader --save-dev

module.exports = {
  module: {//模块
    noParse: /jquery/,//不想解析jquery,因为jquery没有依赖
    rules: [//规则  css-loader 解析@import这种语法
      //style-loader 把css插入到 head 标签中
      //loader 用法 字符串 只用一个loader
      //多个loader需要用数组 []
      //也可用对象形式  用对象的好处是可以传参
      //loader 的执行顺序是从右(下)向左(上)
      //其他css一样
      //sass node-sass sass-loader
      //stylus stylus-loader
      { test: /\.txt$/, use: 'raw-loader' },
      { test: /\.css$/, use:['style-loader', 'css-loader']},
      { test: /\.less$/, 
        use:[//对象形式
      	  {
      	    loader:'style-loader',
      	    options:{//传参
      	      //希望把生成的样式插入到head的顶部,这样就不会覆盖自己写的默认样式
      	      insertAt: 'top',
      	    }
      	  }, 
      	  'css-loader',
      	  'less-loader' //先安装 npm install less less-lodaer --save-dev
      	]
      },
      {text: /\.js$/,
      	exclude: /node_modules/,//排除node_modules目录下的.js
      	include:path.resolve('src'),//只找src目录下的.js
        use: {
        	loader: 'babel-loader',
        	options: {
        		presets: [
        		  '@babel/preset-env',
        		  '@babel/preset-react'//解析react语法
        		]
        	}
        }
      }
    ]
  }
}

监控watch

自动打包,每当监控到代码改动时,实时重新执行打包

文件:webpack.config.js

module.exports = {
  watch: true,
  watchOptions: {//监控的选项
    poll: 1000, //每秒监控1000次
    aggregateTimeout: 500,防抖 ,停止输入后的500毫秒打包
    ignored: /node_modules/, //不需要监控这个文件
  }
}

解析

配置模块如何解析。比如: import _ from ‘lodash’ ,其实是加载解析了lodash.js文件。此配置就是设置加载和解析的方式。

文件:webpack.config.js

module.exports = {
  resolve: {
    //只在node_modules目录里查找,可多写
    modules: [path.resolve('node_modules'),path.resolve('dist')],
    alias:{//别名
    	bootstrap: 'bootstrap/dist/css/bootstrap.css'
    },
    mainFields: ['style','main'],//主入口,先找style,,找不到再去mian里面找
    mainFiles: [],//入口文件的名字 默认找index.js
    extensions:['.js','.css','.json'],//扩展名先找.js,没有再找.css,没有再找.json
  }
}

插件

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

【插件】自动打包生成

文件:webpack.config.js

const path = require('path');
//通过 npm 安装  npm install html-webpack-plugin --save-dev
const HtmlWebpackPlugin = require('html-webpack-plugin'); 

module.exports = {
  output: {
    filename:'bundle.[hash].js',//给文件加哈希 防止缓存
    filename:'bundle.[hash:8].js',//给文件加8位哈希 
    path: path.resolve(__dirname, "dist"),
  }
  plugins:[
    new HtmlWebpackPlugin({
    	template: './src/index.html', //以谁作为模板
    	filename: 'index.html', //打包出来的文件名称
    	minify:{ //压缩
    	  removeAttributeQuotes: true,//删除html里的双引号
    	  collapseWhitespace: true,//压缩为一行
    	},
    	hash: true,//添加哈希戳
    })
  ]
}

【插件】多页面自动打包生成

文件:webpack.config.js

const path = require('path');
//通过 npm 安装  npm install html-webpack-plugin --save-dev
const HtmlWebpackPlugin = require('html-webpack-plugin'); 

module.exports = {
  entry: {
    home: "./src/index.js",
    other: "./src/other.js"
  },
  output: {
    filename:'[name].js',//[name] 相当于home 和 other
    path: path.resolve(__dirname, "dist")
  }
  plugins:[
    new HtmlWebpackPlugin({
    	template: './src/index.html', //以谁作为模板
    	filename: 'home.html', //打包出来的文件名称
    	chunks: ['home'],//表示home.html页面只引入home.js
    	minify:{ //压缩
    	  removeAttributeQuotes: true,//删除html里的双引号
    	  collapseWhitespace: true,//压缩为一行
    	}
    }),
    new HtmlWebpackPlugin({
    	template: './src/index.html', //以谁作为模板
    	filename: 'other.html', //打包出来的文件名称
    	chunks: ['other','home'],//表示home.html页面引入other.js和home.js
    	minify:{ //压缩
    	  removeAttributeQuotes: true,//删除html里的双引号
    	  collapseWhitespace: true,//压缩为一行
    	}
    })
  ]
}

【插件】每次清空打包目录

文件:webpack.config.js

//先安装 npm install clean-webpack-plugin --save-dev
const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
  ..
  plugins: [
    ...
    new CleanWebpackPlugin('/dist') //需要清空的目录文件	
  ]
}

【插件】复制一些文件到目标目录打包

文件:webpack.config.js

//先安装 npm install copy-webpack-plugin --save-dev
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
  ..
  plugins: [
    ...
    new CopyWebpackPlugin([
    	{from: '/doc',to: './dist'},//从文件doc复制到dist文件夹
    ]) 
  ]
}

【插件】添加版权

文件:webpack.config.js

//webpack内置,不用安装
module.exports = {
  ..
  plugins: [
    ...
    new webpack.BannerPlugin('这里写版权信息') 
  ]
}