基于webpack4.x项目实战1-简单使用javascript
基于webpack4.x项目实战2 - 配置一次,多个项目运行css
基于webpack4.x项目实战3 - 手写一个clihtml
webpack在前端开发者的世界再熟悉不过了,网上也不少关于webpack的文章,本身也写一下,加深印象前端
webpack 是js模块打包器,一直在更新,本文是基于webpack4.29.5版本,未来的某一天,发觉本文章的一些配置用不了,那多是webpack已经更新到更高的版本了vue
安装webpack4
和webpack-cli
,因为webpack4中和webpack-cli抽离了,因此须要分别安装,咱们全局安装一个:java
npm install webpack webpack-cli -g
node
搞一个demo试试react
mkdir webpack-demo && cd webpack-demo
npm init -y
复制代码
新建一个index.js文件,./src/index.jswebpack
--package.json
--src
-- index.js
复制代码
webpack4支持0配置,默认./src/index.js
为入口文件,webpack运行时,会根据mode的值采起不一样的默认配置,mode两个可选值:production
和 development
。没有传mode,会有一个警告css3
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
复制代码
解决这个警告,修改package.json
部分,传入mode便可
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
复制代码
development
和production
的区别在于一个代码没压缩,一个有压缩和优化,执行 npm run dev
,就会生产一个./dist/main.js
文件。
若是咱们只是想要一个简单的打包功能,使用默认配置就够用了。都不须要建立webpack.config.js
在咱们的项目中,使用webpack的默认配置明显是不够用的,仍是须要自定义咱们的webpack配置
在咱们的项目根目录,建立webpack.config.js
,webpack配置的概况以下
module.exports = {
entry: '', // 入口文件
output: {}, // 出口文件
module: {}, // 模块相关配置
plugins: [], // 插件相关配置
resolve: { } // 解析模块的可选项
devServer: {}, // 开发服务器相关配置
devtool: 'inline-source-map', //开发工具,好比启动source-map
mode: 'development' // 模式配置 development/production
}
复制代码
接下来,咱们一点点往里面添加内容,以此更好的理解webpack
一些项目中,只有一个入口文件,那么,入口文件和出口文件能够这样配置
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js', // 打包后的文件名称
path: path.resolve(__dirname, 'dist') // 打包后的目录
}
}
复制代码
若是有多个入口,能够将entry配置成一个array或者object,若是是array,则是将多个入口文件最终生成一个出口文件,若是是object,则对应生成多个文件,以下: entry为array
const path = require('path');
module.exports = {
entry: ['./src/a.js', './src/b.js'], 多个入口文件打包为一个js文件
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
}
}
复制代码
entry为object
const path = require('path');
module.exports = {
entry: {
a: './src/a.js',
b: './src/b.js'
},
output: {
filename: '[name].js', // 打包后为a.js和b.js文件
path: path.resolve(__dirname, 'dist')
}
}
复制代码
因为webpack只能处理js,当咱们须要处理其余非js文件时,咱们须要引入对应的loader
咱们想从javaScript 模块中 import 一个 CSS 文件,须要在 module 配置中 安装并添加 style-loader
和 css-loader
:
npm install style-loader css-loader -D
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
复制代码
src/css/style.css
body {
background: red;
}
复制代码
src/index.js
import './css/style.css';
复制代码
打开index.html,能够看到咱们页面的背景色此时为红色。执行编译,css文件将会打包到js文件当中
加载图片,也须要安装对应的loader npm install file-loader url-loader -D
在css引入背景图片时,须要指定一下相对路径
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/, // 加载图片
use: [{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式
name: 'images/[name].[ext]?[hash]', // 图片打包后存放的目录
publicPath: '../' // css图片引用地址,可修正打包后,css图片引用出错的问题
}
}]
},
]
}
复制代码
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
}
复制代码
webpack提供了各类各样的插件,下面介绍几种经常使用的插件,只试过在webpack4.0以上的版本,其余版本没试过,因此若是有报错,那多是版本不支持
使用webpack插件,咱们要写在配置中的plugins里面,在使用插件以前,咱们都须要先安装该插件。下面介绍几个经常使用的插件
该插件的做用为:生成html页面,自动引入js文件,自动消除src引入的缓存问题,上线以前压缩。
使用前安装该插件npm install html-webpack-plugin --save -dev
;
let HtmlWebpackPlugin = require('html-webpack-plugin');
module: {
...
plugins:[
new HtmlWebpakPlugin({
minify:{
collapseWhitespace: true, // 折叠空白区域 也就是压缩代码
removeAttributeQuotes: true // 移除双引号,
},
hash:true, //向html引入的src连接后面增长一段hash值,消除缓存
template:'./src/index.html', // 模板地址
title: 'webpack' // 标题
})
]
}
复制代码
关于该插件的更多使用方法,能够看这里
前面安装的css-loader
在js中引入css文件时,打包后的css是和js混合在一块儿的,若是咱们想打包后的css文件时单独的存在,须要引入这个插件。
安装npm i extract-text-webpack-plugin@next -D
,其中@next表示能够在webpack4中使用
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("css/styles.css"), // 打包后的css文件
]
}
复制代码
关于该插件的更多使用方法,能够看这里
利用postcss中的autoprefixer来为css3自动添加前缀。
安装npm i postcss-loader autoprefixer -D
在根目录下新建postcss.config.js
里面写入
module.exports = {
plugins: [
require('autoprefixer')
]
}
复制代码
webpack.config.js里面,配置postcss-loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
}
]
}
}
复制代码
在package.json上,添加须要支持的版本
"browerslist": [
"last 2 versions",
"IE 8",
"UCAndroid"
],
复制代码
webpack提供的插件很是多,更多的插件,能够看这里
安装npm i -D @babel/core @babel/plugin-transform-runtime @babel/preset-env babel-loader
在webpack.config.js中添加
..略
module:{
rulse:[
...略
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/, // 忽略掉该文件下的js
}
]
}
复制代码
在根目录下,也就是和webpack.config.js同一个目录下,新增.babelrc文件
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime"]
}
复制代码
webpack-dev-server
为自动刷新和模块热替换机制,装上它,能够咱们的改动能够自动刷新
安装npm install webpack-dev-server -D
修改一下咱们的webpack.config.js
var path = require('path');
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'dist'), // 服务器资源的根目录,不写的话,默认为bundle.js
compress: true, // 服务器资源采用gzip压缩
port: 9000, // 运行的端口
overlay: true // 出错代码是否显示在html页面上
hot: true //热加载
}
};
复制代码
再修改咱们的package.json
...
"scripts": {
"dev": "webpack-dev-server --mode development --open",
}
...
复制代码
执行npm run dev
,就会自动打开浏览器,监听你的修改了
注意点:
webpack-dev-server
输出的文件只存在于内存中,不输出真实的文件,也就是说,你启动它,你的dist文件实际上是没有生产新的文件的
resolve是webpack自带的,主要做用是设置模块如何被解析 主要介绍几个:
resolve.alias配置项经过别名来把原来导入路径映射成一个新的导入路径,例如:
resolve: {
alias: {
components: './src/components/'
}
}
复制代码
这样,咱们原来import Dialog from './src/components/dialog'
能够缩减为import Dialog from 'components/dialog'
;
resolve: {
extensions: ['.js', '.json']
}
复制代码
咱们用import data from './data'
时,webpack就会依次寻找data.js是否存在,不存在继续寻找data.json是否存在,最后寻找data/index.js是否存在
Webpack找第三方模块,默认是只会去node_modules
目录下寻找。若是你的项目中,不少模块要引用这个目录下的, 那目录可能很长。打个比方,src/components/test.js要去node_modules
下面找dialog组件,那么可能这样写:import '../../../components/dialog'
,利用resolve.modules
优化后:
resolve.modules:['./src/components','node_modules']
复制代码
你能够简单经过 import 'dialog'
导入。
经过以上的介绍,咱们大概熟悉了webpack的一些基础配置,下面咱们来进入实战
咱们配置具备以下功能的webpack配置:
咱们目录结构以下:
——src
├─components
├─css
└─images
├─index.js
——index.html
——.babelrc
——package.json
——postcss.config.js
——webpack.config.js
复制代码
webpack.config.js的配置以下:
const path = require('path');
const htmlWebpackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'main.js', // 打包后的文件名称
path: path.resolve(__dirname, 'dist') // 打包后的目录
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({ // 拆分单独的css文件
fallback: "style-loader",
use: ['css-loader', 'postcss-loader'] // 加载css
})
},
// 加载less
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ['css-loader', 'postcss-loader']
})
},
{
test: /\.(png|svg|jpg|gif)$/, // 加载图片
use: [{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式
name: 'images/[name].[ext]?[hash]', // 图片打包后的目录
publicPath: '../' // css图片引用地址
},
}]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/, // 加载字体文件
use: [
'file-loader'
]
},
// 转义es6
{
test: /\.js$/,
loader: 'babel-loader',
include: /src/, // 只转化src目录下的js
exclude: /node_modules/, // 忽略掉node_modules下的js
}
]
},
resolve: {
alias: {
components: path.resolve(__dirname, 'src/components/') // 别名
},
extensions: ['.js', '.json'], // 忽略文件后缀
modules: ['node_modules']
},
plugins: [
new htmlWebpackPlugin({
template: "./index.html",
filename: "index.html",
inject: true,
hash: true,
chunksSortMode: 'none' //如使用webpack4将该配置项设置为'none'
}),
new ExtractTextPlugin("css/styles.css"),
new OptimizeCssAssetsPlugin({ // 优化css
cssProcessor: require('cssnano'), //引入cssnano配置压缩选项
cssProcessorOptions: {
discardComments: { removeAll: true }
},
canPrint: true //是否将插件信息打印到控制台
})
],
devServer: {
hot: true,
contentBase: path.join(__dirname, 'dist'),
port: 3002,
},
};
复制代码
代码地址: 这里
目前vue、react都有本身的webpack配置,都已经配好了,直接拿来用便可。不过做为一个优秀的前端,咱们也须要知道如何从零开始配置属于本身的webpack.config.js。 后续写一个只需配置一次,能够多个项目公共的webpack配置,敬请期待...
参考文章: