WebPack能够看作是模块打包机:它作的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。css
构建就是把源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码,包括以下内容。html
构建实际上是工程化、自动化思想在前端开发中的体现,把一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。 构建给前端开发注入了更大的活力,解放了咱们的生产力。前端
mkdir webpack-start cd webpack-start npm init
==> Webpack 启动后会从Entry
里配置的Module
开始递归解析 Entry 依赖的全部 Module。 每找到一个 Module, 就会根据配置的Loader
去找出对应的转换规则,对 Module 进行转换后,再解析出当前 Module 依赖的 Module。 这些模块会以 Entry 为单位进行分组,一个 Entry 和其全部依赖的 Module 被分到一个组也就是一个 Chunk
。最后 Webpack 会把全部 Chunk 转换成文件输出。 在整个流程中 Webpack 会在恰当的时机执行 Plugin 里定义的逻辑。node
npm install webpack webpack-cli -D
npm i webpack-dev-server –D
devServer:{ contentBase:path.resolve(__dirname,'dist'), host:'localhost', compress:true, port:8080 }
"scripts": { "build": "webpack --mode development", "dev": "webpack-dev-server --open --mode development " }
经过使用不一样的Loader,Webpack能够要把不一样的文件都转成JS文件,好比CSS、ES6/七、JSX等react
loader三种写法jquery
npm i style-loader css-loader -D
配置加载器webpack
module: { rules:[ { test:/\.css$/, use:['style-loader','css-loader'], include:path.join(__dirname,'./src'), exclude:/node_modules/ } ] },
咱们但愿自动能产出HTML文件,并在里面引入产出后的资源web
npm i html-webpack-plugin -D
plugins: [ new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, template: './src/index.html', filename:'index.html' })]
npm i file-loader url-loader -D
let logo=require('./images/logo.png'); let img=new Image(); img.src=logo; document.body.appendChild(img);
{ test:/\.(jpg|png|gif|svg)$/, use:'url-loader', include:path.join(__dirname,'./src'), exclude:/node_modules/ }
还能够在CSS文件中引入图片正则表达式
.img-bg{ background: url(./images/logo.png); width:173px; height:66px; }
由于CSS的下载和JS能够并行,当一个HTML文件很大的时候,咱们能够把CSS单独提取出来加载npm
npm install --save-dev extract-text-webpack-plugin@next
{ test:/\.css$/, use: ExtractTextWebpackPlugin.extract({ use:'css-loader' }), include:path.join(__dirname,'./src'), exclude:/node_modules/ }, plugins: [ new ExtractTextWebpackPlugin('css/index.css'),
处理图片路径问题
const PUBLIC_PATH='/'; output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath:PUBLIC_PATH },
指定打包后的图片位置
use: [ { loader: 'url-loader', options: { limit: 1024, outputPath:'images/' } } ],
在HTML中使用图片
npm i html-withimg-loader -D
<div class="img-container "><img src="./images/logo.png" alt="logo.png"></div>
{ test:/\.(html|html)$/, use:'html-withimg-loader', include:path.join(__dirname,'./src'), exclude:/node_modules/ }
npm i less less-loader -D
npm i node-saas sass-loader -D
@color:orange; .less-container{ border:1px solid @color; } $color:green; .sass-container{ border:1px solid $color; }
const cssExtract=new ExtractTextWebpackPlugin('css.css'); const lessExtract=new ExtractTextWebpackPlugin('less.css'); const sassExtract=new ExtractTextWebpackPlugin('sass.css'); { test:/\.less$/, use: lessExtract.extract({ use:['css-loader','less-loader'] }), include:path.join(__dirname,'./src'), exclude:/node_modules/ }, { test:/\.scss$/, use: sassExtract.extract({ use:['css-loader','sass-loader'] }), include:path.join(__dirname,'./src'), exclude:/node_modules/ },
为了浏览器的兼容性,有时候咱们必须加入-webkit,-ms,-o,-moz这些前缀
npm i postcss-loader autoprefixer -D
postcss.config.js
module.exports={ plugins:[require('autoprefixer')] }
.circle {
transform: translateX(100px);
}
{ test:/\.css$/, use: cssExtract.extract({ use:['css-loader','postcss-loader'] }), include:path.join(__dirname,'./src'), exclude:/node_modules/ },
Babel实际上是一个编译JavaScript的平台,能够把ES6/ES7,React的JSX转义为ES5
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react -D
{ test:/\.jsx?$/, use: { loader: 'babel-loader', options: { presets: ["env","stage-0","react"] } }, include:path.join(__dirname,'./src'), exclude:/node_modules/ },
webapck经过配置能够自动给咱们source maps
文件,map
文件是一种对应编译文件和源文件的方法
devtool:'eval-source-map'
import _ from 'lodash';
alert(_.join(['a','b','c'],'@'));
new webpack.ProvidePlugin({ _:'lodash' })
当代码发生修改后能够自动从新编译
new webpack.BannerPlugin('珠峰培训'), watch: true, watchOptions: { ignored: /node_modules/, //忽略不用监听变动的目录 aggregateTimeout: 500, //防止重复保存频繁从新编译,500毫米内重复保存不打包 poll:1000 //每秒询问的文件变动的次数 },
有时项目中没有引用的文件也须要打包到目标目录
npm i copy-webpack-plugin -D
new CopyWebpackPlugin([{ from: path.join(__dirname,'public'),//静态资源目录源地址 to:'./public' //目标地址,相对于output的path目录 }]),
npm i clean-webpack-plugin -D
new cleanWebpaclPlugin(path.join(__dirname,'dist'))
压缩JS可让输出的JS文件体积更小、加载更快、流量更省,还有混淆代码的加密功能
npm i uglifyjs-webpack-plugin -D
plugins: [ new UglifyjsWebpackPlugin(), ]
webpack能够消除未使用的CSS,好比bootstrap中那些未使用的样式
npm i -D purifycss-webpack purify-css
npm i bootstrap -S
{ test:/\.css$/, use: cssExtract.extract({ use: [{ loader: 'css-loader', options:{minimize:true} },'postcss-loader'] }), },
new PurifyCSSPlugin({ //purifycss根据这个路径配置遍历你的HTML文件,查找你使用的CSS paths:glob.sync(path.join(__dirname,'src/*.html')) }),
若是你有单独的后端开发服务器 API,而且但愿在同域名下发送 API 请求 ,那么代理某些 URL 会颇有用。
//请求到 /api/users 如今会被代理到请求 http://localhost:9000/api/users。 proxy: { "/api": "http://localhost:9000", }
proxy: { "/api": { target: "http://localhost:9000", pathRewrite: {"^/api":""} } }
指定extension以后能够不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配
resolve: { //自动补全后缀,注意第一个必须是空字符串,后缀必定以点开头 extensions: ["",".js",".css",".json"], },
配置别名能够加快webpack查找模块的速度
const bootstrap=path.join(__dirname,'node_modules/bootstrap/dist/css/bootstrap.css') resolve: { alias: { 'bootstrap': bootstrap } },
许多 library 将经过与 process.env.NODE_ENV 环境变量关联,以决定 library 中应该引用哪些内容。例如,当不处于生产环境中时,某些 library 为了使调试变得容易,可能会添加额外的日志记录(log)和测试(test)。其实,当使用 process.env.NODE_ENV === 'production' 时,一些 library 可能针对具体用户的环境进行代码优化,从而删除或添加一些重要代码。咱们能够使用 webpack 内置的 DefinePlugin 为全部的依赖定义这个变量:
npm install cross-env -D
"scripts": { "build": "cross-env NODE_ENV=production webpack --mode development", "dev": "webpack-dev-server --open --mode development " },
plugins: [ new webpack.DefinePlugin({ NODE_ENV:JSON.stringify(process.env.NODE_ENV) }),
if (process.env.NODE_ENV == 'development') { console.log('这是开发环境'); } else { console.log('这是生产环境'); }
require("expose-loader?libraryName!./file.js"); require("expose-loader?_!loadash"); let _=require('expose-loader?_!lodash');
{ test: /^lodash$/, loader: "expose?_" }
setTimeout(function(){ console.log(window._); });
有时候咱们的页面能够不止一个HTML页面,会有多个页面,因此就须要多入口
entry: { index: './src/index.js', main:'./src/main.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash].js', publicPath:PUBLIC_PATH }, new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, template: './src/index.html', chunks:['index'], filename:'index.html' }), new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, chunks:['main'], template: './src/main.html', filename:'main.html' })],
若是咱们想引用一个库,可是又不想让webpack打包,而且又不影响咱们在程序中以CMD、AMD或者window/global全局等方式进行使用,那就能够经过配置externals
const $ = require("jquery");
const $ = window.jQuery;
externals: { jquery: "jQuery"//若是要在浏览器中运行,那么不用添加什么前缀,默认设置就是global },