webpack搭建前端框架是现代前端开发的一个基本前提,如果你对webpack不熟悉,可以根据本文从零搭建一个可运行的框架。 本文及源代码都在github上,见仓库xp44mm/hyperscript-rxjs-test。 本文虽然很长,但是都是直接复制,粘贴,无需更改的内容。配置好以后,很少改动,请读者耐心跟随操作。 前端框架hyperscript-rxjs是一个js函数库,可以通过node.js的npm包管理器的方法使用它。我们用到babel和webpack这两个包系列应该是前端必备的工具。测试使用jest。 First let's create a directory, initialize npm: 用文本编辑器打开目录中的package.json,向其中添加依赖项: 其中的依赖并不是全部都需要安装,但是我们只是让他跑起来,性能问题可以需要时再优化,读者可以自行找出不需要的包删除之。 配置webpack,根目录下,webpack.common.js 根目录下,webpack.dev.js 我们用到ES的新特性,需要babel转译,在根目录下添加文件babel.config.js 添加一个文件夹,public,其中添加html的开始模板index.html: 添加一个js代码的入口文件,index.js 这个程序向模板中id为root的元素添加你编写的元素。这个元素可以很复杂,并且带有交互功能。 回到命令行窗口,确保路径是在项目文件夹的根目录。安装包 安装成功后,要想开发运行程序,请执行 稍等片刻,程序会自动打开浏览器,网页标签为hyperscript rxjs test,网页内容是hello world! 想要退出代码服务,在命令行按ctrl + C,键入y则退出。 现代javascript的好处就是代码模块化,所以我们才会使用webpack。我们把框架代码留在主index.js中,具体的元素实现放到其他文件中。新建一个文件夹src,并在其中新建一个文件hello.js: 修改根目录下的index.js 这样我们只需要导入root中的内容,就可以做出千变万化的前端网页。 重新测试,看看程序是否正常。 接下来的教程,只需要要修改第二行的文件路径,就可以测试程序。从零开始用webpack搭建前端框架
先决条件
Basic Setup
mkdir hyperscript-rxjs-test
cd hyperscript-rxjs-test
npm init -y
{
"dependencies": {
"deep-rxjs": "1.0.8",
"hyperscript-rxjs": "1.0.7",
"rxjs": "7.0.0"
},
"devDependencies": {
"@babel/core": "7.14.0",
"@babel/plugin-proposal-class-properties": "7.13.0",
"@babel/plugin-proposal-export-default-from": "7.12.13",
"@babel/plugin-proposal-export-namespace-from": "7.12.13",
"@babel/plugin-proposal-pipeline-operator": "7.12.13",
"@babel/preset-env": "7.14.1",
"@webpack-cli/serve": "1.4.0",
"babel-jest": "26.6.3",
"babel-loader": "8.2.2",
"clean-webpack-plugin": "3.0.0",
"core-js": "3.12.1",
"css-loader": "5.2.4",
"html-loader": "2.1.2",
"html-webpack-plugin": "5.3.1",
"jest": "26.6.3",
"node-fetch": "2.6.1",
"style-loader": "2.0.0",
"tslib": "2.2.0",
"webpack": "5.36.2",
"webpack-cli": "4.7.0",
"webpack-dev-server": "3.11.2",
"webpack-merge": "5.7.3"
},
"scripts": {
"build": "webpack --config webpack.prod.js",
"start": "webpack serve --config webpack.dev.js",
"test": "jest"
},
"name": "hyperscript-rxjs-test"
}
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebPackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
},
resolve: {
extensions: ['.js', '.json'],
modules: [path.resolve(__dirname, 'node_modules')],
},
module: {
rules: [
{
test: /\.js$/,
exclude: [/[\\/]node_modules[\\/]/],
use: [
{
loader: 'babel-loader',
options: { babelrc: true },
},
],
},
{
test: /\.css$/,
exclude: [/[\\/]node_modules[\\/]/],
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
},
{
test: /\.html$/,
exclude: [/[\\/]node_modules[\\/]/],
use: [{ loader: 'html-loader' }],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
exclude: [/[\\/]node_modules[\\/]/],
type: 'asset',
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebPackPlugin({
template: './public/index.html',
favicon: './public/favicon.ico',
}),
],
}
const { merge } = require('webpack-merge')
const common = require('./webpack.common.js')
module.exports = merge(common, {
mode: 'development',
devtool: 'eval-source-map',
output: {
filename: '[name].[contenthash].js',
},
devServer: {
port: 3000,
disableHostCheck: true,
open: true,
},
})
module.exports = function (api) {
api.cache.using(() => process.env.NODE_ENV)
let presets = [
[
'@babel/preset-env',
{
targets: api.env('test') ? { node: 'current' } : { chrome: '90' },
loose: true, // convert from es6 to es5 loosely.
corejs: 3, //declaring a core-js version
useBuiltIns: 'entry',
},
],
]
let plugins = [
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-class-properties',
['@babel/plugin-proposal-pipeline-operator', { proposal: 'fsharp' }],
]
return { presets, plugins }
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>hyperscript rxjs test</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
import { fragment, p } from 'hyperscript-rxjs'
import './style.css'
let elem = p('hello world!')
document.addEventListener('DOMContentLoaded', function () {
const root = document.getElementById('root')
let element = elem instanceof Array ? fragment(...elem) : elem
root.appendChild(element)
})
测试运行
npm i
npm start
合理分割代码
import { p } from 'hyperscript-rxjs'
export const hello = p('hello world!')
import { fragment } from 'hyperscript-rxjs'
import { hello as elem } from './src/hello'
import './style.css'
document.addEventListener('DOMContentLoaded', function () {
const root = document.getElementById('root')
let element = elem instanceof Array ? fragment(...elem) : elem
root.appendChild(element)
})