webpack v4 从dev到prd的方法

概述

本月迎来了 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 模式。

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

eg:

webpack --mode development

Usage

    Some Plugin options are now validated
    CLI has been move to webpack-cli, you need to install webpack-cli to use the CLI
    The ProgressPlugin (–progress) now displays plugin names
    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

    css-loader
    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?\");

/***/ })

/******/ });

未完待续

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

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

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容