ES6及以上版本的 js 文件在一些低版本浏览器上不能执行,所以当项目开发完成后,我们需要对 js 文件进行编译,将ES6+的语法转译为 ES5。这里我们使用gulp的webpack-stream插件来对js文件进行打包。解决js转译的问题需要用到babel,我们在这里使用webpack 的 babel-loader。具体操作往下看。
webpack-stream
先来认识一下webpack-stream,我们都知道webpack的功能非常强大,但是在,批量式处理方面,依然是gulp更胜一筹,通过使用webpack-stream,可以将webpack作为‘流’运行,集成到gulp中。
1、安装
npm install --save-dev webpack-stream
#或者使用yarn安装
yarn add webpack-stream -D
2、webpack.config.js
一个简单的 webpack.config.js文件内容如下:
module.exports = {
mode: "development",
devtool:"inline-source-map",//调试工具显示
entry: "./src/js/app.js",
output: {
path: "/home/dev/",
filename: "app.js"
},
module:{} //下面有该内容的详细介绍
}
webpack的配置项:
- mode,设置环境模式,告知 webpack 使用相应模式的内置优化;
- development,表示开发环境;
- production,表示生产环境;
- devtool,源映射,可以设置在浏览器控制台中代码的显示方式;
- 默认在控制台显示编译后的代码内容;
- source-map,在控制台显示源代码;
- inline-source-map,表示将源映射内联到文件中;
- entry,入口文件,可以配置多个入口点;
entry: './path/to/my/entry/file.js'
,表示只有一个入口文件;entry:{pageOne:'./src/pageOne/index.js',pageTwo:'./src/pageTwo/index.js'}
,设置多页面应用程序;
- output,导出文件的路径,即使存在多个入口,也只能指定一个输出配置。
- path,目标输出目录,是一个绝对路径;
- filename,输出文件的文件名,当存在多个入口文件时,使用 [name]对应entry 中的key;
- module,模块,通过 loader 可以支持各种语言和预处理器编写模块;
3、导入gulpfile.js
将webpack.config.js文件导入gulpfile.js中:
const {src,series,dest} = require("gulp");
const webpack = require("webpack-stream");
const webpackConfig = require ("./webpack.config.js");
const path = require("path");
function compileJs() {
return src("./src/js/**/*.js")
.pipe(webpackStream(webpackConfig))
.pipe(dest("./dev/"))
}
exports.default = series(compileJs)
在终端中直接输入gulp启动服务,就可以看到打包好的文件了。
现在我们可以实现使用webpack-stream对js文件进行打包输出,但是如果在 js 中,我们使用的是 ES2015+ 的语法,会出现低版本浏览器不兼容的问题,所以我们需要对打包的文件进行编译,这里用到下面两个插件。
babel-loader
它的作用是加载 ES2015+ 代码,然后使用 Babel 转译为 ES5。
1、安装
npm install babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/runtime --save-dev
//或者使用yarn安装
yarn add babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/runtime -D
2、用法
在 webpack 配置对象中,需要添加 babel-loader 到 module 的 loaders 列表中,可以使用 options 属性来给 loader 传递选项,像下面这样:
module: {
rules: [
{
test: /\.js$/, //需要编译的文件
exclude: /node_modules/, //排除 node_modules目录
use: {
loader: "babel-loader", //loader名称
options: { //配置
presets: ['@babel/preset-env'], //预设
plugins: ['@babel/plugin-transform-runtime']//插件
}
}
}
]
}
3、注意事项
- 确保转译尽可能少的文件。你可能使用 /.js$/ 来匹配,这样也许会去转译 node_modules 目录或者其他不需要的源代码。为了提高 babel-loader 的速度,需要使用exclude,排除 node_modules目录;
- 引入 babel-plugin-transform-runtime ,使所有辅助代码从这里引用。它可以避免重复引入,减小代码体积;
点击查看关于babel的详细介绍。
string-loader
它的作用是将资源文件转换为字符串。可以搭配 art-template 模板引擎一起使用,提高开发效率。
例如当我们在js文件中引入下面这个html文件时,会自动将这个html文件换成字符串。
import ItemTpl from "../../views/position/position-item.html";
console.log(ItemTpl); //“<html>......</html>”
1、安装
npm install string-loader --save-dev
//或者使用yarn来安装
yarn add string-loader -D
2、用法
将html转换为字符串模板:
module: {
rules: [
{
test:/\.html$/,
loader:"string-loader"
}
]
}
将json转换为字符串模板:
module: {
rules: [
{
test:/\.json$/,
loader:"string-loader"
}
]
}
gulp编译js的完整代码
到此为止,通过使用 babel-loader 、string-loader 这两个插件,我们可以将js文件转译为兼容任何浏览器的ES5语法。
gulpfile.js文件如下:
const {src,series,dest} = require("gulp");
const concat = require("gulp-concat");
const webpackStream = require("webpack-stream");
const path = require("path");
function compileJs() {
return src("./src/js/**/*.js")
.pipe(webpackStream({
mode: "development",
devtool:"inline-source-map",
entry: {
main:"./src/js/app.js",
detail:"./src/js/detail.js"
},
output: {
path: path.resolve(__dirname, "./dev/"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['@babel/preset-env'], //预设
plugins: ['@babel/plugin-transform-runtime']
}
}
},
{
test:/\.html$/,
loader:"string-loader"
}
]
}
}))
.pipe(dest("./dev/"))
}
exports.default = series(compileJs);