本月迎来了 v4 正式版的发布,本文用于学习新特性和总结开发必用plugin & loader,从dev到prd,走你~css
本次新版本中引入了 mode 配置项,开发者可在 none,development(开发 ) 以及 production(产品)三种模式间选择。该配置项缺省状况下默认使用 production 模式。html
eg:node
webpack --mode development
复制代码
新版中将 webpack 命令行工具拆分到单独的仓库中,因此须要额外安装 webpack-cli。react
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",
},
复制代码
module: {
rules:[
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
}
复制代码
css-loader用来解析处理CSS文件中的url路径,jquery
要把CSS文件变成一个模块 多个loader是有顺序要求的,从右往左写,由于转换的时候是从右往左转换webpack
此插件先用css-loader处理一下css文件,再用style-loader把CSS文件变成style标签插入head中web
module: {
rules:[
{
test: /\.css$/,
loader: ["style-loader", "css-loader"]
},
]
}
复制代码
module: {
rules:[
{
test: /\.css$/,
use:[
{ loader:"style-loader"},
{
loader: 'css-loader',
options: {sourceMap: true}
}
]
}
]
}
复制代码
这三种loader的写法,最后打包的结果相同ajax
loader中的options配置项能够用"?"跟在加载器后面npm
eg:json
{
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/' } } } 复制代码
(1)加载bootstrap
要在模块中引入bootstrap须要在js中加入
import 'bootstrap/dist/css/bootstrap.css'
复制代码
可是这样相对麻烦,咱们能够作相关修改,将这句代码简化成
import 'bootstrap'
复制代码
简化方法以下:
在webpack中配置别名alias,能够加快webpack查找模块的速度
每当引入bootstrap模块的时候,它会直接引入bootstrapPath,而不须要从node_modules文件夹中按模块的查找规则查找
不须要webpack去解析bootstrap文件
const bootstrap=path.join(__dirname,'node_modules/bootstrap/dist/css/bootstrap.css')
resolve: {
+ alias: {
+ 'bootstrap': bootstrap
+ }
},
复制代码
安装依赖
npm i bootstrap url url-loader style-loader css-loader --save
复制代码
在webpack.js中配置bootstrap中css 图片 字体等文件的解析依赖
loaders: [
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
{ test: /\.(woff|woff2)$/, loader:"url?prefix=font/&limit=5000" },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" }
]
复制代码
(2)若是须要使用bootstrap的js插件的话,就必须首先引入jquery。引用jquery的一个方法是使用webpack插件。
首先安装jquery:
npm i jquery
复制代码
在webpack中用插件装入jquery
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
复制代码
在入口文件内加入代码来作验证:
$("body").append("<div>hello world</div>")
复制代码
讲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中
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的用法
它会将全部的入口 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
]
复制代码
rules: {
test: /\.js$/,
loader:'babel-loader',
include: path.resolve(__dirname, 'src'),//只转换或者编译src 目录 下的文件
exclude: /node_modules/ //不要解析node_modules
}
复制代码
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出的对象
若是交换mainFields中的key顺序
mainFields: ['main', 'node','browser']
复制代码
打包后 console.log出的对象,由于找到了key=node对应的文件就中止了查找
这个插件是在 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节选
打包出来的react_dll.js节选
可见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
复制代码
打包速度显著变快
打包后的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?");
/***/ })
/******/ });
复制代码