webpack v4 从dev到prd的方法


Posted in Javascript onApril 02, 2018

概述

本月迎来了 v4 正式版的发布,本文用于学习新特性和总结开发必用plugin & loader,从dev到prd,走你~

Big changes

Environment

Node.js 4 is no longer supported. Source Code was upgraded to a higher ecmascript version.

Usage

You have to choose (mode or --mode) between two modes now: production or development

本次新版本中引入了 mode 配置项,开发者可在 none,development(开发 ) 以及 production(产品)三种模式间选择。该配置项缺省情况下默认使用 production 模式。

  1. development 模式给你极致的开发体验,包含浏览器调试相关工具,极快的增量编译,丰富全面的报错信息...
  2. production 模式则包含大量发版优化,代码压缩,丝般润滑的运行时优化,开发相关代码的排除,易用,etc.
  3. none 不使用预设,等于老版本中全部自己配置的原始状态。

eg:

webpack --mode development

Usage

  1. Some Plugin options are now validated
  2. CLI has been move to webpack-cli, you need to install webpack-cli to use the CLI
  3. The ProgressPlugin (--progress) now displays plugin names
  4. At least for plugins migrated to the new plugin system

新版中将 webpack 命令行工具拆分到单独的仓库中,所以需要额外安装 webpack-cli。

npm init -y //初始化项目
npm install webpack webpack-cli -D //安装webpack webpack-cli 依赖
npx webpack --mode development // npx可以直接运行node_modules/.bin目录下面的命令

或者通过配置package.json的script build

"scripts": {
 "build": "webpack --mode development",
},

加载loader方法总结

use

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

css-loader用来解析处理CSS文件中的url路径,要把CSS文件变成一个模块

多个loader是有顺序要求的,从右往左写,因为转换的时候是从右往左转换

此插件先用css-loader处理一下css文件,再用style-loader把CSS文件变成style标签插入head中

loader

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

use+loader

module: {
 rules:[
  {
   test: /\.css$/,
   use:[
    { loader:"style-loader"},
    { 
     loader: 'css-loader',
     options: {sourceMap: true}
    }
   ]
  }
 ]
}

这三种loader的写法,最后打包的结果相同

loader中的options配置项可以用"?"跟在加载器后面

eg:

{ 
 test: /\.jpeg$/, 
 use: 'url-loader?limit=1024&name=[path][name].[ext]&outputPath=img/&publicPath=output/', 
}

为以下配置的简写

{ 
 test: /\.jpeg$/, 
 use: {
  loader:'url-loader',
  options:{
   limit:1024,
   name:[path][name].[ext],
   outputPath:img/
   publicPath:output/'
  }
 }
}

开发必备的loader&plugins

  1. css-loader
  2. babel-loader

讲ES6代码转换为ES5

{
 test: /\.js/,
 use: {
  loader: 'babel-loader',
  query: {
   presets: ["env", "stage-0", "react"]
  }
 }
},

babel-loader的预设可以添加在query中,也可以在项目根目录添加 .babelrc 文件

.babelrc
{
 "presets": [
  "env",
  "stage-0",
  "react"
 ]
}

html-webpack-plugin

插件的基本作用就是生成html文件。原理很简单:

将 webpack中entry配置的相关入口thunk  和  extract-text-webpack-plugin抽取的css样式   插入到该插件提供的template或者templateContent配置项指定的内容基础上生成一个html文件,具体插入方式是将样式link插入到head元素中,script插入到head或者body中。

const HtmlWebpackPlugin = require('html-webpack-plugin');

new HtmlWebpackPlugin({
 template: './src/index.html',//指定产的HTML模板
 filename: `index.html`,//产出的HTML文件名
 title: 'index',
 hash: true,// 会在引入的js里加入查询字符串避免缓存,
 minify: {
  removeAttributeQuotes: true
 }
}),

可以用 cnpm search html-webpack-plugin 查找想用loader的用法

less-loader sass-loader

优化向prd进发

提取公共的css代码

它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。

npm i extract-text-webpack-plugin@next -D
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
let cssExtract = new ExtractTextWebpackPlugin({
 filename: 'css/css.css',
 allChunks: true
});
module:{
 rules:[
  {
   test: /\.css$/,//转换文件的匹配正则
   loader: cssExtract.extract({
    use: ["css-loader?minimize"]
   })
  },
 ]
}
plugins:[
 ...... ,
 + cssExtract
]

尽量减少文件解析,用resolve配置文件解析路径,include

rules: {
 test: /\.js$/,
 loader:'babel-loader',
 include: path.resolve(__dirname, 'src'),//只转换或者编译src 目录 下的文件
 exclude: /node_modules/ //不要解析node_modules
}

resolve.mainFields

WebpackTest
|
|
| - src
| | - index.js
|
| - lib
| | - fetch
|  |
|  browser.js
|  node.js
|  package.json
|
| - webpack.config.js

当从 npm 包中导入模块时(例如,引入lib下的库),此选项将决定在 package.json 中使用哪个字段导入模块。根据 webpack 配置中指定的 target 不同,默认值也会有所不同。

package.json

lib文件夹下的package.json中配置相对应模块的key

{
 "name": "fetch",
 "version": "1.0.0",
 "description": "",
 "node": "./node.js",
 "browser": "./browser.js",
 "scripts": {
 "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [],
 "author": "",
 "license": "ISC"
}

webpack.config.js

在resolve解析对象中,加入lib的路径

resolve: {
 extensions: ['.js', '.json'],
 mainFields: ['main', 'browser', 'node'],
 modules: [path.resolve('node_modules'), path.resolve('lib')]
}

index.js

这样在index.js中引用第三方库时,会去查找modules下的路径中是否配置了所需的文件,知道在package.json中找到mainFields中的key对应文件,停止。

let fetch = require('fetch');
console.log(fetch);

打包后 console.log出的对象

webpack v4 从dev到prd的方法

如果交换mainFields中的key顺序

mainFields: ['main', 'node','browser']

打包后 console.log出的对象,因为找到了key=node对应的文件就停止了查找

webpack v4 从dev到prd的方法

DllReferencePlugin

这个插件是在 webpack 主配置文件中设置的, 这个插件把只有 dll 的 bundle(们)(dll-only-bundle(s)) 引用到需要的预编译的依赖。

新建webpack.react.config.js

const path = require('path');
const webpack = require('webpack')
module.exports = {
 entry: {
  react: ['react', 'react-dom']
 },
 output: {
  path: path.join(__dirname, 'dist'),// 输出动态连接库的文件名称
  filename: '[name]_dll.js',
  library: '_dll_[name]'//全局变量的名字,其它会从此变量上获取到里面的模块
 },
 // manifest 表示一个描述文件
 plugins: [
  new webpack.DllPlugin({
   name: '_dll_[name]',
   path: path.join(__dirname, 'dist', 'manifest.json')//最后打包出来的文件目录和名字
  })
 ]
}

在entry入口写入要打包成dll的文件,这里把体积较大的react和react-dom打包

output中的关键是library的全局变量名,下文详细说明dll&manifest工作原理

打包dll文件

webpack --config webpack.react.config.js --mode development

打包出来的manifest.json节选

webpack v4 从dev到prd的方法

打包出来的react_dll.js节选

webpack v4 从dev到prd的方法

可见manifest.json中的 name值就是

output:{
  library:_dll_react
}

manifest.json就是借书证,_dll_react就像图书馆书籍的条形码,为我们最终找到filename为react_dll.js的参考书

使用“参考书”

在webpack.config.js中加入“借书证”

new webpack.DllReferencePlugin({
  manifest: path.join(__dirname, 'dist', 'manifest.json')
})

再运行

webpack --mode development

打包速度显著变快

webpack v4 从dev到prd的方法

打包后的main.js中,react,react-dom.js也打包进来了,成功~

import React from 'react';\n//import ReactDOM from 'react-dom';
 (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\n//import name from './base';\n//import React from 'react';\n//import ReactDOM from 'react-dom';\n//import ajax from 'ajax';\n//let result = ajax('/ajax');\n\n//ReactDOM.render(<h1>{result}</h1>, document.getElementById('root'));\n// fetch fetch.js fetch.json fetch文件夹\n//let fetch = require('fetch');\n//console.log(fetch);\n//let get = require('../dist/bundle.js');\n//get.getName();\nconsole.log('hello');\n\nvar name = 'zfpx';\nconsole.log(name);\nif (true) {\n  var s = 'ssssssssssssssssssssssss';\n  console.log(s);\n  console.log(s);\n  console.log(s);\n  console.log(s);\n}\n\n//# sourceURL=webpack:///./src/index.js?");

/***/ })

/******/ });

未完待续

  1. webpack.ProvidePlugin
  2. 拷贝静态资源
  3. 压缩css(npm i -D purifycss-webpack purify-css)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
为JavaScript类型增加方法的实现代码(增加功能)
Dec 29 Javascript
jQuery function的正确书写方法
Aug 02 Javascript
下拉列表选择项的选中在不同浏览器中的兼容性问题探讨
Sep 18 Javascript
9行javascript代码获取QQ群成员具体实现
Oct 16 Javascript
基于jQuery实现的旋转彩圈实例
Jun 26 Javascript
bootstrap3 兼容IE8浏览器!
May 02 Javascript
AngularJS压缩JS技巧分析
Nov 08 Javascript
深入理解JavaScript继承的多种方式和优缺点
May 12 Javascript
node使用UEditor富文本编辑器的方法实例
Jul 11 Javascript
浅谈关于iview表单验证的问题
Sep 29 Javascript
LayUI数据接口返回实体封装的例子
Sep 12 Javascript
ESLint 是如何检查 .vue 文件的
Nov 30 Vue.js
vue axios登录请求拦截器
Apr 02 #Javascript
webpack+react+antd脚手架优化的方法
Apr 02 #Javascript
vue axios请求超时的正确处理方法
Apr 02 #Javascript
JavaScript 日期时间选择器一些小结
Apr 02 #Javascript
vue计算属性及使用详解
Apr 02 #Javascript
vue小白入门教程
Apr 02 #Javascript
Angular父组件调用子组件的方法
Apr 02 #Javascript
You might like
php判断输入不超过mysql的varchar字段的长度范围
2011/06/24 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
PHP实现生成唯一编号(36进制的不重复编号)
2014/07/01 PHP
一个简洁实用的PHP缓存类完整实例
2014/07/26 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
php定时执行任务设置详解
2015/02/06 PHP
Yii2实现ajax上传图片插件用法
2016/04/28 PHP
搭建自己的PHP MVC框架详解
2017/08/16 PHP
为你的 Laravel 验证器加上多验证场景的实现
2020/04/07 PHP
Jsonp 跨域的原理以及Jquery的解决方案
2011/06/27 Javascript
jQuery插件bxSlider实现响应式焦点图
2015/04/12 Javascript
jquery实现全选功能效果的实现代码
2016/05/05 Javascript
类似于QQ的右滑删除效果的实现方法
2016/10/16 Javascript
深入理解JavaScript创建对象的多种方式以及优缺点
2017/06/01 Javascript
react-native-fs实现文件下载、文本存储的示例代码
2017/09/22 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
2019/04/13 Javascript
javascript实现一款好看的秒表计时器
2020/09/05 Javascript
详解JavaScript中的链式调用
2020/11/27 Javascript
使用cx_freeze把python打包exe示例
2014/01/24 Python
详解Python函数式编程—高阶函数
2019/03/29 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
PyQt5 界面显示无响应的实现
2020/03/26 Python
Pycharm自带Git实现版本管理的方法步骤
2020/09/18 Python
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
be2台湾单身男女交友:全球网路婚姻介绍的领导品牌
2019/10/11 全球购物
教你怎样写好自我评价
2013/10/05 职场文书
实习单位推荐信范文
2013/11/27 职场文书
给幼儿园老师的表扬信
2014/01/19 职场文书
《听鱼说话》教学反思
2014/02/15 职场文书
加入学生会演讲稿
2014/04/24 职场文书
同学聚会策划方案
2014/06/06 职场文书
员工保密协议书
2014/09/27 职场文书
CSS3 制作的悬停缩放特效
2021/04/13 HTML / CSS
为什么RedisCluster设计成16384个槽
2021/09/25 Redis
win11如何查看端口是否被占用? Win11查看端口是否占用的技巧
2022/04/05 数码科技