webpack 本质上是一个打包工具,它会根据代码的内容解析模块依赖,帮助咱们把多个模块的代码打包。借用 webpack 官网的图片:javascript
虽然webpack4.x的版本能够零配置开始构建,可是在实际的项目中须要其它的一些功能,仍是须要一个配置文件。css
下面一步一步讲解配置一个基本的前端开发环境过程。html
首先本身环境中安装了有node(自带npm)。若是你的项目中没有package.json,那么须要使用npm init。前端
会在项目下生成一个package.json文件,其中会有以下代码:vue
{ "name": "test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
咱们如今来使用npm来安装webpack,能够做为一个全局的命令来使用:java
npm install webpack webpack-cli -g
其中webpack-cli是使用webpack的命令行工具。在 4.x 版本以后再也不做为 webpack 的依赖了,咱们使用时须要单独安装这个工具。node
更多的时候咱们是把webpack做为项目的依赖来安装使用的。webpack
npm install webpack webpack-cli -D
package.json文件就会多了以下配置:git
"devDependencies": { "webpack": "^4.27.1", "webpack-cli": "^3.1.2" }
咱们在package.json中添加一个npm scripts:github
代码以下:
"scripts": { "build": "webpack --mode production" }, "devDependencies": { "webpack": "^4.27.1", "webpack-cli": "^3.1.2" }
而后咱们建立一个'./src/index.js',其中index.js中的代码任意写,如:
export default { a:'字符串' }
而后执行npm run build后会在项目下增长了一个dist文件夹,里面存放了webpack构建好的main.js文件。
由于是做为项目依赖进行安装,因此不会有全局的命令,npm 会帮助咱们在当前项目依赖中寻找对应的命令执行,若是是全局安装的 webpack,直接执行webpack --mode production就能够。
webpack 的几个重要的概念:入口,loader,plugin,输出。
所谓入口,就是webpack的构建入口。webpack会读取这个文件,并从它这儿开始解析依赖,而后进行打包。如上面操做,一开始webpack默认的构建入口就是'./src/index.js'。
在咱们的项目中,若是是单页面应用,通常就只有一个入口;若是是多页面,那么就会配置成一个页面一个构建入口。
入口可使用entry字段来设置,webpack支持配置多个入口进行构建打包:
module.exports = { entry: './src/index.js' } // 上述配置等同于 module.exports = { entry: { main: './src/index.js' } } // 或者配置多个入口 module.exports = { entry: { foo: './src/page-foo.js', bar: './src/page-bar.js', // ... } } // 使用数组来对多个文件进行打包 module.exports = { entry: { main: [ './src/foo.js', './src/bar.js' ] } }
最后的例子,能够理解为多个文件做为一个入口,webpack 会解析两个文件的依赖后进行打包。
webpack 中提供一种处理多种文件格式的机制,即是使用 loader。咱们能够把 loader 理解为是一个转换器,负责把某种文件格式的内容转换成 webpack 能够支持打包的模块。
举个例子,好比你的入口文件index.js引入了css样式,那么构建的时候就须要用css-loader来处理这些.css文件,同时还须要style-loader。最终打包的结果就是把不一样类型的文件都解析成js代码,以便在打包后能在浏览器中运行。
当咱们须要使用不一样的 loader 来解析处理不一样类型的文件时,咱们能够在module.rules字段下配置相关的规则,好比使用babel来转化js代码:
module: { // ... rules: [ { test: /\.jsx?/, // 匹配文件路径的正则表达式,一般咱们都是匹配文件类型后缀 include: [ path.resolve(__dirname, 'src') // 指定哪些路径下的文件须要通过 loader 处理 ], use: 'babel-loader', // 指定使用的 loader }, ], }
后面有笔记会详细记录下loader的使用以及怎样开发loader。
在webpack的构建工做中,除了用loader来处理模块代码的转换,剩下的工做就是用plugin来完成,下面列举经常使用的几个:
JS代码压缩配置以下:
const UglifyPlugin = require('uglifyjs-webpack-plugin') module.exports = { plugins: [ new UglifyPlugin() ], }
webpack 的输出即指 webpack 最终构建出来的静态文件。构建结果的文件名、路径等都是能够配置的,使用output字段:
module.exports = { // ... output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', }, } // 或者多个入口生成不一样文件 module.exports = { entry: { foo: './src/foo.js', bar: './src/bar.js', }, output: { filename: '[name].js', path: __dirname + '/dist', }, } // 路径中使用 hash,每次构建时会有一个不一样 hash 值,避免发布新版本时线上使用浏览器缓存 module.exports = { // ... output: { filename: '[name].js', path: __dirname + '/dist/[hash]', }, }
咱们刚开始构建的webpack,默认的构建结果就是'./dist/main.js'。
上面总结了几个webpack的重要概念后,来看一个简单的配置例子,webpack运行时默认读取项目下的webpack.config.js文件做为配置,那么咱们如今就在项目下建立一个webpack.config.js文件:
const path = require('path') const UglifyPlugin = require('uglifyjs-webpack-plugin') //js压缩插件 module.exports = { entry:'./src/index.js', output:{ path:path.resolve(__dirname,'dist'), filename:'bundle.js' }, module:{ rules:[ { test:/\.jsx?/,//匹配js,jsx文件 include:[ path.resolve(__dirname,'src') ], use:'babel-loader' } ] }, // 代码模块路径解析的配置 resolve: { modules: [ "node_modules", path.resolve(__dirname, 'src') ], extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"], }, plugins:[ new UglifyPlugin() //使用uglifyjs-webpack-plugin压缩JS代码 //根据上面第一次的构建,你会发现webpack默认使用了JS的代码压缩插件 //这其实也是命令中的 --mode production的效果 ] }
当你直接运行npm run build命令的时候,会报错Cannot find module 'uglifyjs-webpack-plugin'。这儿你须要安装以下内容:
vue-cli 使用 webpack 模板生成的项目文件中,webpack 相关配置存放在 build 目录下。如今的脚手架vue-cli的webpack好像仍是用的webpack3.x版本,要注意下版本区别。
咱们构建基本的前端开发环境须要作哪些事情:
下面围绕这些要求要构建开发环境。
当咱们构建打包完成生成了JS文件,怎样把JS文件跟html页面相关联呢,也就是html怎样引入js文件。固然可使用script标签引入js文件,可是若是打包构建的js路径变化或者使用了hash命名,那么直接引入js文件就不合理了,这时就须要使用html-webpack-plugin
把html-webpack-plugin安装到项目依赖中去:
npm install html-webpack-plugin -D
首先本身按照下列目录建立模板html文件,‘./src/assets/index.html’,html内容随便写,以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>这是构建的第一个web页面</title> </head> <body> </body> </html>
将html-webpack-plugin配置到webpack.config.js中的plugins列表中:
module.exports = { // ... plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 配置输出文件名和路径 template: 'assets/index.html', // 配置文件模板 }), ], }
这样,经过 html-webpack-plugin 就能够将咱们的页面和构建 JS 关联起来,这样将会产生一个包含如下内容的文件dist/index.html。打开index.html能够看到构建后的代码以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>这是构建的第一个web页面</title> </head> <body> <script type="text/javascript" src="bundle.js"></script></body> </html>
详细了解可参考文档html-webpack-plugin, 官网提供的例子html-webpack-plugin/examples/
咱们构建CSS须要使用css-loader和style-loader。
module.exports = { module: { rules: [ // ... { test: /\.css/, include: [ path.resolve(__dirname, 'src'), ], use: [ 'style-loader', 'css-loader', ], }, ], } }
注:style-loader 和 css-loader 都是单独的 node package,须要安装。
咱们建立一个index.css,在index.js中引入:
import './index.css'
index.css里面随便编写一段css代码:
.title{ font-weight: bold; font-size:20px; color:red; }
模板index.html改为以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <div class="title">这是一个主题</div> </body> </html>
安装style-loader与css-loader:
npm install style-loader css-loader --save-dev
如今执行npm run build,而后去看生成的index.html,效果有了,css样式添加上了。可是并无生成css文件。
解释下css-loader跟style-loader的做用:
和url()
等引用外部文件的声明;若是须要单独把 CSS 文件分离出来,咱们须要使用extract-text-webpack-plugin.
因为webpack4.x的extract-text-webpack-plugin版本尚未发布正式版,安装的时候须要指定使用它的 alpha 版本:
npm install extract-text-webpack-plugin@next -D
配置:
const ExtractTextPlugin = require('extract-text-webpack-plugin') module.exports = { // ... module: { rules: [ { test: /\.css$/, // 由于这个插件须要干涉模块转换的内容,因此须要使用它对应的 loader use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader', }), }, ], }, plugins: [ // 引入插件,配置文件名,这里一样可使用 [hash] new ExtractTextPlugin('index.css'), ], }
而后就会在dist文件夹下多生成一个index.css文件。详细可参考:extract-text-webpack-plugin
一般咱们在编写css的时候,常用less或者sass等css预处理器,咱们以less为例,咱们把index.css改为index.less以下:
@fontSize:20px; .title{ font-weight: bold; font-size:@fontSize; color:red; }
安装less-loader,官网文档对应loader:
npm install --save-dev less-loader less
对应的配置文件修改成:
module.exports = { // ... module: { rules: [ { test: /\.less$/, // 由于这个插件须要干涉模块转换的内容,因此须要使用它对应的 loader use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ 'css-loader', 'less-loader', ], }), }, ], }, // ... }
虽然css-loader会解析样式中用url()引用的文件路径,可是图片有jpg/png/gif格式,webpack处理不了,须要使用一个loader配置才行,这就用到了file-loader。
file-loader 能够用于处理不少类型的文件,它的主要做用是直接输出文件,把构建后的文件路径返回。
配置以下:
module.exports = { // ... module: { rules: [ { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: {}, }, ], }, ], }, }
安装file-loader,官方文档file-loader:
npm install --save-dev file-loader
我在index.js引入一张图片:
import '../assets/a.jpg'
运行结果默认在dist目录下生成了78414f2de9fc47d29f335727a717bc3d.jpg。默认状况下,生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名。
固然也能够配置输出路径,文件名称等,以下:
{ test:/\.(jpg|png|gif)$/, use:[ { loader:'file-loader', options:{ name: '[path][name].[ext]', outputPath: 'images/' } } ] }
安装url-loader,详细文档请参考官网url-loader:
url-loader功能相似于file-loader
,可是在文件大小(单位 byte)低于指定的限制时,能够返回一个 DataURL。
npm install --save-dev url-loader
配置:
module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/i, use: [ { loader: 'url-loader', options: { limit: 8192 } } ] } ] } }
Babel是一个让咱们可以使用 ES 新特性的 JS 编译工具,咱们能够在 webpack 中配置 Babel,以便使用 ES六、ES7 标准来编写 JS 代码。
前面已经写过配置了,代码以下:
module.exports = { // ... module: { rules: [ { test: /\.jsx?/, // 支持 js 和 jsx include: [ path.resolve(__dirname, 'src'), // src 目录下的才须要通过 babel-loader 处理 ], loader: 'babel-loader', }, ], }, }
Babel 的相关配置能够在目录下使用 .babelrc 文件来处理,详细参考 Babel 官方文档 .babelrc
咱们可使用 webpack-dev-server 在本地开启一个简单的静态服务来进行开发。
安装webpack-dev-server:
npm install webpack-dev-server --save-dev
而后添加启动命令到 package.json 中:
"scripts": { "build": "webpack --mode production", "start": "webpack-dev-server --mode development" }
而后运行npm run start,而后就能够访问 http://localhost:8080/ 来查看你的页面了。默认是访问 index.html,若是是其余页面要注意访问的 URL 是否正确。
根据上面的配置,咱们已经完成了配置一个简单的前端开发环境,实现了:构建 HTML、CSS、JS 文件、使用 CSS 预处理器来编写样式、处理和压缩图片、使用 Babel、方便开发调试的静态服务。下面的笔记会记录webpack的一些细节来更好的了解webpack。