【9月学习随笔】关于Webpack
-
Webpack是什么
Webpack是将模块打包成一个或多个bundle文件的打包器
-
为什么需要Webpack
结合阮一峰老师的Demo和不使用Webpack的Demo,对比来看为什么需要Webpack
-
更简洁方便的依赖包管理
Webpack-Demo3:
项目结构:
webpack.config.js:
babel-loader会在编译之前将jsx文件翻译为普通ES5语法的文件
module.exports = { entry: './main.jsx', output: { filename: 'bundle.js' }, module: { rules: [ { test: /\.jsx?$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['es2015', 'react'] } } } ] } };
什么是loader
loader 是一种预处理器,它可以在 Webpack 编译之前把你应用中的静态资源进行转换 (更多信息)。
index.html:
引入打包后的bundle.js,无需再引入react依赖
<script src="bundle.js"></script>
Simple-Demo3:
项目结构:
index.html:
引入react和react-dom依赖,由于chrome不支持使用XHR(XMLHttpRequest)加载file:// 开头的url文件,所以只能将react内容直接写在script标签里,或者将jsx内容放在服务器上
<!DOCTYPE html> <head> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script> </head> <body> <h1>Hello Demo</h1> <div id="wrapper"></div> <!-- <script type="text/babel" src='./main.jsx'></script> XHR不支持直接引入本地jsx文件--> <script type='text/babel'> ReactDOM.render( <h2>Content</h2>, document.querySelector('#wrapper') ); </script> </body> </html>
-
更简洁方便的样式表管理
同理我们可以使用不同的loader对不同的文件进行翻译,并打包
webpack.config.js:
使用style-loader和css-loader翻译样式表
module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, module: { rules:[ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, ] } };
-
局部样式和全局样式
css-loader?modules
的 CSS Module 功能可以给 JS 模块的 CSS 设置一个局部作用域。你可以用 :global(selector)
关掉它,使样式变成全局的。
app.css
/* local scope */ .h1 { color: red; } /* global scope */ :global(.h2) { color: blue; }
main.jsx
var React = require('react') var ReactDOM = require('react-dom') var style = require('./app.css') ReactDOM.render( <div> <h1 className={style.h1}>Hello World</h1> <h2 className="h2">Hello Webpack</h2> </div>, document.getElementById('example') )
webpack.config.js
module.exports = { entry: './main.jsx', output: { filename: 'bundle.js' }, module: { rules: [ { test: /\.js[x]?$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['es2015', 'react'] } } }, { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', // 开启 CSS Module 功能 options: { modules: true } } ] } ] } }
效果:
h1受局部样式影响,为红色
h2受全局样式影响,为蓝色
-
拆分模块/自动化分离
为了减少请求,我们将代码打包到同一个js文件里,但如果这个js文件太大,反而会对性能有负面影响。因此更优的方案是将代码拆分为多个模块,按需加载,同时可以利用浏览器的缓存,再次使用时直接从缓存内读取。这样可以大大提升加载的速度。
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: ({ resource }) => ( resource && resource.indexOf('node_modules') >= 0 && resource.match(/\.js$/) ), }), /* 如果某些模块是来自 node_modules 目录的,并且名字是 .js 结尾的话,把他们都移到 vendor chunk 里去,如果 vendor chunk 不存在的话,就创建一个新的。 */
-
Webpack Plugin
-
html-webpack-plugin
生成 html 文件。将 webpack 中entry
配置的相关入口 chunk
和 extract-text-webpack-plugin
抽取的 css 样式 插入到该插件提供的template
或者templateContent
配置项指定的内容基础上生成一个 html 文件,具体插入方式是将样式link
插入到head
元素中,script
插入到head
或者body
中。
var HtmlwebpackPlugin = require('html-webpack-plugin') var OpenBrowserPlugin = require('open-browser-webpack-plugin') module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, plugins: [ new HtmlwebpackPlugin({ title: 'Webpack-demos', filename: 'index.html' }), new OpenBrowserPlugin({ url: 'http://localhost:8080' }) ] }
编译后会直接打开一个新窗口。
-
clean-webpack-plugin
clean-webpack-plugin
用于在打包前清理上一次项目生成的 bundle 文件,它会根据 output.path
自动清理文件夹。如果不进行清理的话每次都会生成新的,导致文件夹非常庞大。
const { CleanWebpackPlugin } = require('clean-webpack-plugin') plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname, '/index.html'), }), new CleanWebpackPlugin(), // 所要清理的文件夹名称 ]
-
extract-text-webpack-plugin
将 css 成生文件,而非内联 。抽离 css 样式,防止将样式打包在 js 中引起页面样式加载错乱的现象
const ExtractTextPlugin = require('extract-text-webpack-plugin') plugins: [ // 将css分离到/dist文件夹下的css文件夹中的index.css new ExtractTextPlugin('css/index.css'), ]