在 Aurelia-CLI 中导入 bootstrap 4 会导致找不到模块
Importing bootstrap 4 in Aurelia-CLI results in Module not found
最近开始使用 Aurelia,我在导入时遇到了一些问题 bootstrap 4。
我已经使用带有 typescript 和基本 webpack 设置的 Aurelia-CLI 设置了应用程序。
我最初尝试按照此处的指南进行操作:https://aureliacasts.com/blog/2018/01/05/aurelia-app-with-bootstrap-4/ 但最终出现错误“找不到模块:错误:无法在 'C:\project\app\src'[=18 中解析 'bootstrap/css/bootstrap.css' =]
我已经用 npm 安装了 jQuery、Bootstrap 和 Popper:
npm i jquery bootstrap popper.js --save
我修改了我的 /aurelia_project/aurelia.json 文件以包含以下依赖项:
"dependencies": [
"jquery",
{
"name": "popper.js",
"path": "../node_modules/popper.js/dist/umd",
"main": "popper.min"
},
{
"name": "bootstrap",
"path": "../node_modules/bootstrap/dist",
"main": "js/bootstrap.min",
"deps": ["jquery"],
"exports": "$",
"resources": [
"css/bootstrap.css"
]
}
]
在我的 app.ts 中我有
import { PLATFORM } from 'aurelia-pal';
import { Router, RouterConfiguration } from 'aurelia-router';
import 'bootstrap';
export class App {
public router: Router;
public configureRouter(config: RouterConfiguration, router: Router){
config.title = 'My second app';
config.options.pushState = true;
config.map([
{ route: ['','home'], name: 'home', moduleId: PLATFORM.moduleName('routes/home/index'), nav: true, title: 'Home'},
{ route: 'about', name: 'about', moduleId: PLATFORM.moduleName('routes/about/index'), nav:true, title: 'About'}
]);
this.router = router;
}
}
最后在我的 app.html 我有:
<template>
<require from="bootstrap/css/bootstrap.css"></require>
<!-- Top navigation -->
<require from="./components/top-navigation/top-navigation.html"></require>
<top-navigation router.bind="router"></top-navigation>
<!-- Renderpage -->
<router-view></router-view>
</template>
修改 aurelia.json 文件后,我确保停止 AU 并使用 "au run --watch"
重新开始,但是我仍然收到以下错误:
ERROR in ./src/app.html Module not found: Error: Can't resolve
'bootstrap/css/bootstrap.css' in 'C:\project\app\src'
@ ./src/app.html @ ./src/app.ts @ ./src/main.ts @
./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js @ multi
aurelia-webpack-plugin/runtime/empty-entry
aurelia-webpack-plugin/runtime/pal-loader-entry
aurelia-webpack-plugin/runtime/empty-entry
aurelia-webpack-plugin/runtime/pal-loader-entry aurelia-bootstrapper
以防其他人偶然发现这个问题,我使用 webpack 解决了它。
我删除了 /aurelia_project/aurelia.json.
下的 "dependencies"
我删除了
<require from="bootstrap/css/bootstrap.css"></require>
来自 app.html,并从 app.ts 中删除了以下内容:
import 'bootstrap';
然后在 webpack.config.js 中我将 const cssRules 修改为(添加了 postcss-loader 和选项,添加了 jquery 和 boostrap 到 module.exports -> entry -> vendor 和 module rules I全局公开 jquery):
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
const { AureliaPlugin, ModuleDependenciesPlugin } = require('aurelia-webpack-plugin');
const { ProvidePlugin } = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || [];
const when = (condition, config, negativeConfig) =>
condition ? ensureArray(config) : ensureArray(negativeConfig);
// primary config:
const title = 'Aurelia Navigation Skeleton';
const outDir = path.resolve(__dirname, project.platform.output);
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';
const cssRules = [
{ loader: 'css-loader' },
{ loader: 'postcss-loader',
options: { plugins: () => [require('autoprefixer')({ browsers: ['last 2 versions']})]}}
];
module.exports = ({production, server, extractCss, coverage, analyze} = {}) => ({
resolve: {
extensions: ['.ts', '.js'],
modules: [srcDir, 'node_modules'],
},
entry: {
app: ['aurelia-bootstrapper'],
vendor: ['bluebird', 'jquery', 'bootstrap'],
},
mode: production ? 'production' : 'development',
output: {
path: outDir,
publicPath: baseUrl,
filename: production ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js',
sourceMapFilename: production ? '[name].[chunkhash].bundle.map' : '[name].[hash].bundle.map',
chunkFilename: production ? '[name].[chunkhash].chunk.js' : '[name].[hash].chunk.js'
},
performance: { hints: false },
devServer: {
contentBase: outDir,
// serve index.html for all 404 (required for push-state)
historyApiFallback: true
},
devtool: production ? 'nosources-source-map' : 'cheap-module-eval-source-map',
module: {
rules: [
// CSS required in JS/TS files should use the style-loader that auto-injects it into the website
// only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
{
test: /\.css$/i,
issuer: [{ not: [{ test: /\.html$/i }] }],
use: extractCss ? ExtractTextPlugin.extract({
fallback: 'style-loader',
use: cssRules
}) : ['style-loader', ...cssRules],
},
{
test: /\.css$/i,
issuer: [{ test: /\.html$/i }],
// CSS required in templates cannot be extracted safely
// because Aurelia would try to require it again in runtime
use: cssRules
},
{ test: /\.html$/i, loader: 'html-loader' },
{ test: /\.tsx?$/, loader: "ts-loader" },
{ test: /\.json$/i, loader: 'json-loader' },
// use Bluebird as the global Promise implementation:
{ test: /[\/\]node_modules[\/\]bluebird[\/\].+\.js$/, loader: 'expose-loader?Promise' },
// exposes jQuery globally as $ and as jQuery:
{ test: require.resolve('jquery'), loader: 'expose-loader?$!expose-loader?jQuery' },
// embed small images and fonts as Data Urls and larger ones as files:
{ test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
{ test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
{ test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
// load these fonts normally, as files:
{ test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
...when(coverage, {
test: /\.[jt]s$/i, loader: 'istanbul-instrumenter-loader',
include: srcDir, exclude: [/\.{spec,test}\.[jt]s$/i],
enforce: 'post', options: { esModules: true },
})
]
},
plugins: [
new AureliaPlugin(),
new ProvidePlugin({
'Promise': 'bluebird',
'$': 'jquery',
'jQuery': 'jquery',
'window.jquery':'jquery',
Popper: ['popper.js', 'default'] // Bootstrap 4 dependency
}),
new ModuleDependenciesPlugin({
'aurelia-testing': [ './compile-spy', './view-spy' ]
}),
new HtmlWebpackPlugin({
template: 'index.ejs',
minify: production ? {
removeComments: true,
collapseWhitespace: true
} : undefined,
metadata: {
// available in index.ejs //
title, server, baseUrl
}
}),
...when(extractCss, new ExtractTextPlugin({
filename: production ? '[contenthash].css' : '[id].css',
allChunks: true
})),
...when(production, new CopyWebpackPlugin([
{ from: 'static/favicon.ico', to: 'favicon.ico' }])),
...when(analyze, new BundleAnalyzerPlugin())
]
});
最后一步是在 main.ts 顶部导入 boostrap:
import 'bootstrap/dist/css/bootstrap.css';
最近开始使用 Aurelia,我在导入时遇到了一些问题 bootstrap 4。 我已经使用带有 typescript 和基本 webpack 设置的 Aurelia-CLI 设置了应用程序。
我最初尝试按照此处的指南进行操作:https://aureliacasts.com/blog/2018/01/05/aurelia-app-with-bootstrap-4/ 但最终出现错误“找不到模块:错误:无法在 'C:\project\app\src'[=18 中解析 'bootstrap/css/bootstrap.css' =]
我已经用 npm 安装了 jQuery、Bootstrap 和 Popper:
npm i jquery bootstrap popper.js --save
我修改了我的 /aurelia_project/aurelia.json 文件以包含以下依赖项:
"dependencies": [
"jquery",
{
"name": "popper.js",
"path": "../node_modules/popper.js/dist/umd",
"main": "popper.min"
},
{
"name": "bootstrap",
"path": "../node_modules/bootstrap/dist",
"main": "js/bootstrap.min",
"deps": ["jquery"],
"exports": "$",
"resources": [
"css/bootstrap.css"
]
}
]
在我的 app.ts 中我有
import { PLATFORM } from 'aurelia-pal';
import { Router, RouterConfiguration } from 'aurelia-router';
import 'bootstrap';
export class App {
public router: Router;
public configureRouter(config: RouterConfiguration, router: Router){
config.title = 'My second app';
config.options.pushState = true;
config.map([
{ route: ['','home'], name: 'home', moduleId: PLATFORM.moduleName('routes/home/index'), nav: true, title: 'Home'},
{ route: 'about', name: 'about', moduleId: PLATFORM.moduleName('routes/about/index'), nav:true, title: 'About'}
]);
this.router = router;
}
}
最后在我的 app.html 我有:
<template>
<require from="bootstrap/css/bootstrap.css"></require>
<!-- Top navigation -->
<require from="./components/top-navigation/top-navigation.html"></require>
<top-navigation router.bind="router"></top-navigation>
<!-- Renderpage -->
<router-view></router-view>
</template>
修改 aurelia.json 文件后,我确保停止 AU 并使用 "au run --watch"
重新开始,但是我仍然收到以下错误:
ERROR in ./src/app.html Module not found: Error: Can't resolve 'bootstrap/css/bootstrap.css' in 'C:\project\app\src' @ ./src/app.html @ ./src/app.ts @ ./src/main.ts @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry aurelia-bootstrapper
以防其他人偶然发现这个问题,我使用 webpack 解决了它。
我删除了 /aurelia_project/aurelia.json.
下的 "dependencies"我删除了
<require from="bootstrap/css/bootstrap.css"></require>
来自 app.html,并从 app.ts 中删除了以下内容:
import 'bootstrap';
然后在 webpack.config.js 中我将 const cssRules 修改为(添加了 postcss-loader 和选项,添加了 jquery 和 boostrap 到 module.exports -> entry -> vendor 和 module rules I全局公开 jquery):
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
const { AureliaPlugin, ModuleDependenciesPlugin } = require('aurelia-webpack-plugin');
const { ProvidePlugin } = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || [];
const when = (condition, config, negativeConfig) =>
condition ? ensureArray(config) : ensureArray(negativeConfig);
// primary config:
const title = 'Aurelia Navigation Skeleton';
const outDir = path.resolve(__dirname, project.platform.output);
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';
const cssRules = [
{ loader: 'css-loader' },
{ loader: 'postcss-loader',
options: { plugins: () => [require('autoprefixer')({ browsers: ['last 2 versions']})]}}
];
module.exports = ({production, server, extractCss, coverage, analyze} = {}) => ({
resolve: {
extensions: ['.ts', '.js'],
modules: [srcDir, 'node_modules'],
},
entry: {
app: ['aurelia-bootstrapper'],
vendor: ['bluebird', 'jquery', 'bootstrap'],
},
mode: production ? 'production' : 'development',
output: {
path: outDir,
publicPath: baseUrl,
filename: production ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js',
sourceMapFilename: production ? '[name].[chunkhash].bundle.map' : '[name].[hash].bundle.map',
chunkFilename: production ? '[name].[chunkhash].chunk.js' : '[name].[hash].chunk.js'
},
performance: { hints: false },
devServer: {
contentBase: outDir,
// serve index.html for all 404 (required for push-state)
historyApiFallback: true
},
devtool: production ? 'nosources-source-map' : 'cheap-module-eval-source-map',
module: {
rules: [
// CSS required in JS/TS files should use the style-loader that auto-injects it into the website
// only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
{
test: /\.css$/i,
issuer: [{ not: [{ test: /\.html$/i }] }],
use: extractCss ? ExtractTextPlugin.extract({
fallback: 'style-loader',
use: cssRules
}) : ['style-loader', ...cssRules],
},
{
test: /\.css$/i,
issuer: [{ test: /\.html$/i }],
// CSS required in templates cannot be extracted safely
// because Aurelia would try to require it again in runtime
use: cssRules
},
{ test: /\.html$/i, loader: 'html-loader' },
{ test: /\.tsx?$/, loader: "ts-loader" },
{ test: /\.json$/i, loader: 'json-loader' },
// use Bluebird as the global Promise implementation:
{ test: /[\/\]node_modules[\/\]bluebird[\/\].+\.js$/, loader: 'expose-loader?Promise' },
// exposes jQuery globally as $ and as jQuery:
{ test: require.resolve('jquery'), loader: 'expose-loader?$!expose-loader?jQuery' },
// embed small images and fonts as Data Urls and larger ones as files:
{ test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
{ test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
{ test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
// load these fonts normally, as files:
{ test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
...when(coverage, {
test: /\.[jt]s$/i, loader: 'istanbul-instrumenter-loader',
include: srcDir, exclude: [/\.{spec,test}\.[jt]s$/i],
enforce: 'post', options: { esModules: true },
})
]
},
plugins: [
new AureliaPlugin(),
new ProvidePlugin({
'Promise': 'bluebird',
'$': 'jquery',
'jQuery': 'jquery',
'window.jquery':'jquery',
Popper: ['popper.js', 'default'] // Bootstrap 4 dependency
}),
new ModuleDependenciesPlugin({
'aurelia-testing': [ './compile-spy', './view-spy' ]
}),
new HtmlWebpackPlugin({
template: 'index.ejs',
minify: production ? {
removeComments: true,
collapseWhitespace: true
} : undefined,
metadata: {
// available in index.ejs //
title, server, baseUrl
}
}),
...when(extractCss, new ExtractTextPlugin({
filename: production ? '[contenthash].css' : '[id].css',
allChunks: true
})),
...when(production, new CopyWebpackPlugin([
{ from: 'static/favicon.ico', to: 'favicon.ico' }])),
...when(analyze, new BundleAnalyzerPlugin())
]
});
最后一步是在 main.ts 顶部导入 boostrap:
import 'bootstrap/dist/css/bootstrap.css';