webpack是一个现代JavaScript应用程序的静态模块打包器,借用官网的一张图,它可以将一些预处理语言,js的最新语法转换成浏览器识别的内容。如今通常的前端框架都有比较成熟的脚手架,大多数对webpack都有个较好的集成,咱们只须要敲一些简单的命令就能生成一个通用的项目模板,比较便捷,可是要知其然知其因此然,因此今天就尝试着从零开始搭建一个前端开发环境。css
项目源码:html
https://github.com/gerryli0214/webpack-demo前端
webpack的四个核心概念:node
一、入口(entry)webpack
二、输出(output)git
三、loaderes6
四、插件(plugins)github
首先,咱们执行下npm init;初始化一个node工程,填写项目的信息,整个项目的目录结构以下:web
所有安装webpack-cli:npm
npm install webpack-cli -g
安装项目webpack依赖:
npm install webpack webpack-cli -D
新建一个webpack.config.js,这个是webpack默认配置文件,在里面咱们能够配置打包信息,初始化文件为:
const config = {};
module.exports = config;
入口(entry):
项目的入口文件,能够配置单个/多个,为入口文件的相对路径,type:string/object;咱们项目入口文件为index.js。
const config = { entry: './src/index.js' } module.exports = config;
输出(output):
打包后的文件路径和配置信息,path为打包文件路径,filename为输出文件名称,name为原始文件名称,hash为打包后的hash地址:
output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash].min.js' }
loader:
loader可以处理非JavaScript文件,webpack默认只能处理JavaScript文件。在使用loader时,首先要安装下指定loader的依赖,此部分的配置规则与以前版本有所差别,具体配置以下:
npm install babel-loader css-loader -D
module: { rules: [{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) }, { test: /\.js/, exclude: /node_modules/, //过滤node_modules文件夹 use: [{ loader: 'babel-loader' }] } ] }
插件(plugins):
插件是webpack最为强大的功能之一,利用插件,咱们能够进行代码的混淆、压缩、从新定义项目环境变量等。插件分为webpack内置插件和第三方插件,第三方插件在使用时首先要安装依赖和导入依赖模块。详细的使用方法能够参考npm。下面罗列了几个项目中经常使用的插件:
html-webpack-plugin:
主要做用:
一、为html文件中引入的外部资源如script
、link
动态添加每次compile后的hash,防止引用缓存的外部文件问题
二、能够生成建立html入口文件,好比单页面能够生成一个html文件入口,配置多个就能够打包成多页面
extract-text-webpack-plugin:
主要做用:分离打包的css文件
uglifyjs-webpack-plugin:
主要做用:混淆js代码
webpack-bundle-analyzer:
主要做用:生成打包文件报告,能够看到各个模块打包后文件大小信息
clean-webpack-plugin:
主要做用:每次打包以前清除dist文件夹
配置信息以下:
1 const path = require('path'); 2 const webpack = require('webpack'); 3 const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 const ExtractTextPlugin = require('extract-text-webpack-plugin'); 5 const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 6 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 7 const CleanWebpackPlugin = require('clean-webpack-plugin'); 8 9 const config = { 10 entry: './src/index.js', 11 output: { 12 path: path.resolve(__dirname, 'dist'), 13 filename: '[name].[hash].min.js' 14 }, 15 module: { 16 rules: [{ 17 test: /\.css$/, 18 use: ExtractTextPlugin.extract({ 19 fallback: 'style-loader', 20 use: 'css-loader' 21 }) 22 }, 23 { 24 test: /\.js/, 25 exclude: /node_modules/, //过滤node_modules文件夹 26 use: [{ 27 loader: 'babel-loader' 28 }] 29 } 30 ] 31 }, 32 optimization: { 33 splitChunks: { 34 name: "vendor", 35 filename: 'vendor-[hash].min.js' 36 }, 37 minimizer: [new UglifyJsPlugin()] 38 }, 39 plugins: [ 40 new HtmlWebpackPlugin({ template: './src/index.html' }), 41 new ExtractTextPlugin({ 42 filename: 'build.min.css', 43 allChunks: true, 44 }), 45 new webpack.BannerPlugin({ 46 banner: `构建时间:${new Date().getFullYear()}-${new Date().getMonth()+1}-${new Date().getDate()}` 47 }), 48 new CleanWebpackPlugin(), 49 // new webpack.EnvironmentPlugin({ NODE_ENV: 'production' }), 50 new BundleAnalyzerPlugin() 51 ] 52 }; 53 54 module.exports = config;
以上为打包的基础配置信息,在咱们实际开发中,常常会用到前端开发服务,模块热更新以及前端的跨域请求代理,webpack中提供了webpack-dev-server来知足咱们的需求,在使用以前先安装下webpack-dev-server的依赖:
npm install webpack-dev-server -D
具体文件配置以下:
devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, host: '0.0.0.0', port: 9000, hot: true, //是否热更新 proxy: { //代理 '/api': 'http://localhost:3000' } }
package.json中启动命令配置以下:
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server --mode development", "build": "webpack --mode production" }
执行npm run start,执行结果以下:
这样开发环境咱们的主要配置就完成了,可是当咱们用uglifyjs压缩es6代码时,会发现会报错,由于uglifyjs不能压缩es6的代码,此时咱们须要手动配置下babel,具体步骤以下:
一、安装项目依赖
npm install @babel/core @babel/preset-env -D
二、新建在项目根目录下.babelrc文件,填入如下配置信息
{ "presets":["@babel/preset-env"] }
执行npm run build,压缩项目代码,结果以下:
所有代码:
const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const CleanWebpackPlugin = require('clean-webpack-plugin'); const config = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash].min.js' }, module: { rules: [{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) }, { test: /\.js/, exclude: /node_modules/, //过滤node_modules文件夹 use: [{ loader: 'babel-loader' }] } ] }, optimization: { splitChunks: { name: "vendor", filename: 'vendor-[hash].min.js' }, minimizer: [new UglifyJsPlugin()] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new ExtractTextPlugin({ filename: 'build.min.css', allChunks: true, }), new webpack.BannerPlugin({ banner: `构建时间:${new Date().getFullYear()}-${new Date().getMonth()+1}-${new Date().getDate()}` }), new CleanWebpackPlugin(), // new webpack.EnvironmentPlugin({ NODE_ENV: 'production' }), new BundleAnalyzerPlugin() ], devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, host: '0.0.0.0', port: 9000, hot: true, //是否热更新 proxy: { //代理 '/api': 'http://localhost:3000' } }, devtool: 'source-map' }; module.exports = config;
参考资料:
webpack中文网:https://www.webpackjs.com
webpack内置插件列表:https://www.webpackjs.com/plugins/
第三方插件可自行搜索npm:https://www.npmjs.com/
项目源码:
https://github.com/gerryli0214/webpack-demo
文笔比较粗糙,若有问题,烦请指出,谢谢!