打包工具:Webpack
参考:
官网:https://webpack.js.org/guides/getting-started/
原文:https://segmentfault.com/a/1190000021395777
本文demo(webpack5):https://gitee.com/open_-_code/webpack_demo.git
webpack demo
1 初始化项目
初始化npm
npm init -y
安装依赖
npm install webpack webpack-cli --save-dev
创建src文件,src下创建index.js
// index.js console.log('hello webpack')
配置package.json
"scripts": { "build": "webpack" },
执行npm run build
此时如果生成了一个dist文件夹,并且内部含有main.js说明已经打包成功了
2 配置自己的配置
新建一个webpack.config.js
// webpack.config.js const path = require('path'); module.exports = { mode:'development', // 开发模式 entry: './src/index.js', // 入口文件 output: { filename: 'main.js', // 打包后的文件名称 path: path.resolve(__dirname, 'dist'), // 打包后的目录 }, };
更改package.json
"scripts": { "build": "webpack --config webpack.config.js" },
执行npm run build,其中dist
文件夹中的main.js
就是我们需要在浏览器中实际运行的文件
3 配置html模板
为了缓存,日常开发时,webpack.config.js往往会这样配置
// webpack.config.js const path = require('path'); module.exports = { mode:'development', // 开发模式 entry: './src/index.js', // 入口文件 output: { filename: '[name].[hash:8].js', // 打包后的文件名称 path: path.resolve(__dirname, 'dist'), // 打包后的目录 }, };
你会发现打包好的js文件的名称每次都不一样
webpack打包出来的js文件我们需要引入到html中,但是每次我们都手动修改js文件名显得很麻烦,因此我们需要一个插件来帮我们完成这件事情
npm i -D html-webpack-plugin
新建文件夹public,
里面新建一个index.html
引入插件html-webpack-plugin,修改webpack.config.js
// webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode:'development', // 开发模式 entry: './src/index.js', // 入口文件 output: { filename: '[name].[hash:8].js', // 打包后的文件名称 path: path.resolve(__dirname, 'dist'), // 打包后的目录 }, plugins:[ new HtmlWebpackPlugin({ template:path.resolve(__dirname,'./public/index.html') }) ] };
执行打包命令,打包生成的js文件已经被自动引入html文件中
多文件入口开发,修改webpack.config.js
// webpack.config.js plugins:[ new HtmlWebpackPlugin({ template:path.resolve(__dirname,'./public/index.html'), filename:'index.html', chunks:['main'] // 与入口文件对应的模块名 }), new HtmlWebpackPlugin({ template:path.resolve(__dirname,'./public/header.html'), filename:'header.html', chunks:['header'] // 与入口文件对应的模块名 }), ]
执行打包命令生成目录
每次执行npm run build 会发现dist文件夹里会残留上次打包的文件,这里我们推荐一个plugin来帮我们在打包输出前清空文件夹clean-webpack-plugin
npm i -D clean-webpack-plugin
// webpack.config.js const {CleanWebpackPlugin} = require('clean-webpack-plugin') module.exports = { // ...省略其他配置 plugins:[new CleanWebpackPlugin()] }
4 引入css
我们的入口文件是js,所以我们在入口js中引入我们的css文件
// index.js import '/src/assets/index.css' import '/src/assets/index.less' console.log('hello webpack')
同时我们也需要一些loader来解析我们的css文件
npm i -D style-loader css-loader
如果我们使用less来构建样式,则需要多安装两个
npm i -D less less-loader
// webpack.config.js module.exports = { // ...省略其他配置 module:{ rules:[ { test:/\.css$/, use:['style-loader','css-loader'] // 从右向左解析原则 }, { test:/\.less$/, use:['style-loader','css-loader','less-loader'] // 从右向左解析原则 } ] } }
执行打包命令,浏览器打开dist下的index.html
4.1 为css添加浏览器前缀
npm i -D postcss-loader autoprefixer
// webpack.config.js module.exports = { // ...省略其他配置 module:{ rules:[ { test:/\.less$/, use:['style-loader','css-loader','postcss-loader','less-loader'] // 从右向左解析原则 } ] } }
根目录下创建postcss.config.js
// postcss.config.js module.exports = () => { return { plugins: { 'autoprefixer': { overrideBrowserslist: ['Android >= 4.0', 'iOS >= 7'] }, } } }
这时候我们发现css通过style标签的方式添加到了html文件中,但是如果样式文件很多,全部添加到html中,难免显得混乱。这时候我们想用把css拆分出来用外链的形式引入css文件怎么做呢?这时候我们就需要借助插件来帮助我们
4.2 拆分css
webpack 4.0以前,我们通过extract-text-webpack-plugin
插件,把css样式从js文件中提取到单独的css文件中。webpack4.0以后,官方推荐使用mini-css-extract-plugin
插件来打包css文件
npm i -D mini-css-extract-plugin
// webpack.config.js const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { //...省略其他配置 module: { rules: [ { test:/\.css$/, use:[MiniCssExtractPlugin.loader,'css-loader','postcss-loader'] // 从右向左解析原则 }, { test:/\.less$/, use:[MiniCssExtractPlugin.loader,'css-loader','less-loader','postcss-loader'] // 从右向左解析原则 }, ] }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[hash].css", chunkFilename: "[id].css", }) ] }
5 打包图片、字体、媒体等文件
file-loader
就是将文件在进行一些处理后(主要是处理文件名和路径、解析文件url),并将文件移动到输出的目录中
url-loader
一般与file-loader
搭配使用,功能与 file-loader 类似,如果文件小于限制的大小。则会返回 base64 编码,否则使用 file-loader 将文件移动到输出的目录中
// webpack.config.js module.exports = { // 省略其它配置 ... module: { rules: [ // ... { test: /\.(jpe?g|png|gif)$/i, //图片文件 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, //媒体文件 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'media/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, // 字体 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'fonts/[name].[hash:8].[ext]' } } } } ] }, ] } }
6 用babel转义js文件
npm install -D babel-loader @babel/core @babel/preset-env
-
- 注意
babel-loader
与babel-core
的版本对应关系
babel-loader
8.x 对应babel-core
7.xbabel-loader
7.x 对应babel-core
6.x
// webpack.config.js module.exports = { // 省略其它配置 ... module:{ rules:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:['@babel/preset-env'] } }, exclude:/node_modules/ }, ] } }
上面的babel-loader
只会将 ES6/7/8语法转换为ES5语法,但是对新api并不会转换 例如(promise、Generator、Set、Maps、Proxy等)
cnpm i @babel/polyfill -D
// webpack.config.js const path = require('path') module.exports = { entry: ["@babel/polyfill",path.resolve(__dirname,'./src/index.js')], // 入口文件 }
over!!