Answer the question
In order to leave comments, you need to log in
How to customize script output in a specific location using Webpack?
Hello! It is necessary to configure the output of the script directly on the page, like maps, for further interaction with the back. On the page it should look like this:
<div class="content__main">
<div class="cells">
<div class="cell cell-xl-8">
<div id="app-cart">
<script>
import { createApp } from "vue";
import App from "./App.vue";
import store from "./vuex/store.js";
let cartApp = document.querySelector("#app-cart");
if (cartApp) {
createApp(App, { URL: "http://localhost:3000/products" })
.use(store)
.mount("#app-cart");
}
</script>
</div>
</div>
Cannot use import statement outside a module
createApp is not defined
<div class="cell cell-xl-8">
<div id="app-cart">
<script src="assets/js/cart.js"></script>
<script>
let cartApp = document.querySelector("#app-cart");
if (cartApp) {
createApp(App, { URL: "http://localhost:3000/products" })
.use(store)
.mount("#app-cart");
}
</script>
</div>
</div>
const webpack = require("webpack");
const path = require("path");
const fs = require("fs");
const {
CleanWebpackPlugin
} = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const {
VueLoaderPlugin
} = require('vue-loader');
// const CompressionPlugin = require('compression-webpack-plugin');
// const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
// const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const pages = fs
.readdirSync(path.resolve(__dirname, "src/templates/pages"))
.filter((fileName) => fileName.endsWith(".pug"));
module.exports = (env, options) => ({
entry: {
main: "./src/index.js",
theming: "./src/js/theming.js",
cart: "./src/cart-vue/cart-vue.js"
},
output: {
publicPath: "",
path: path.resolve(__dirname, "dist"),
filename: "assets/js/[name].js"
},
devtool: "source-map",
// devServer: {
// static: "./dev",
// port: 3000
// },
module: {
rules: [
{
test: /\.pug$/,
include: path.resolve(__dirname, "src/templates"),
use: [
{
loader: "pug-loader",
options: {
pretty: true
}
}
]
},
{
test: /\.(scss|css)$/,
include: path.resolve(__dirname, "src/sass"),
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../../"
}
},
{
loader: "css-loader"
},
{
loader: "postcss-loader"
},
{
loader: "resolve-url-loader"
},
{
loader: "sass-loader",
options: {
sourceMap: true,
sassOptions: {
outputStyle: "expanded"
}
}
}
]
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
include: /theme-images/,
type: "asset/resource",
generator: {
filename: "assets/images/[name][ext]"
}
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
include: /content-images/,
type: "asset/resource",
generator: {
filename: "assets/content-images/[name][ext]"
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: "asset/resource",
generator: {
filename: "assets/fonts/[name][ext]"
}
},
{
test: /\.vue$/,
include: path.resolve(__dirname, "src/cart-vue"),
loader: "vue-loader"
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components|vendor)/,
include: path.resolve(__dirname, "src"),
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"]
}
}
}
]
},
plugins: [
options.mode === "development" ? false : new CleanWebpackPlugin(),
// new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "assets/css/[name].css"
}),
new VueLoaderPlugin(),
...pages.map(
page =>
new HtmlWebpackPlugin({
template: "./src/templates/pages/" + page,
chunks: ["main", "theming"],
filename: page.replace(/\.pug/, ".html"),
minify: false
})
),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./src/templates/pages/cart-vue.pug"),
chunks: ["main", "theming", "cart"],
filename: "cart-vue.html",
minify: false
}),
// new webpack.ProvidePlugin({
// // $: "jquery",
// // jQuery: "jquery",
// // "window.jQuery": "jquery",
// }),
new ImageminPlugin({
bail: false, // Ignore errors on corrupted images
cache: true,
imageminOptions: {
pngquant: {
quality: "95-100"
}
}
}),
new CopyPlugin({
patterns: [
{
from: "src/js/vendor/*.js",
to: "assets/js/vendor/[name].js"
},
{
from: "src/sass/vendor/*.css",
to: "assets/css/vendor/[name].css"
},
{
from: "src/images/content-images/*.jpg",
to: "assets/content-images/[name].jpg"
}
]
})
].filter(n => n)
// optimization: {
// minimizer: [
// new UglifyJsPlugin({
// cache: true,
// parallel: true,
// sourceMap: false,
// extractComments: false
// }),
// new CompressionPlugin({
// test: /\.js$|\.css(\?.*)?$/i
// }),
// new OptimizeCSSAssetsPlugin({})
// ]
// }
});
Answer the question
In order to leave comments, you need to log in
If you want webpack to output the plug-in bundle with scripts not to the end of the document, but to a certain place, then you need to:
1 disable auto-plugin in HTMLWebpackPlugin (inject: false). In my example it was like this:
plugins: [
new HTMLWebpackPlugin({
templateParameters: {
'foo': 'bar'
},
template: './index.html',
inject: false,
meta: {
charset: { charset: 'utf-8' },
viewport: 'width=device-width, initial-scale=1'
},
minify: {
removeComments: isProd,
collapseWhitespace: isProd
}
}),
]
<%= htmlWebpackPlugin.tags.bodyTags %>
<script type="module">
Learn Syntax Modules Introduction
<script type="module">
webpack collects js in a closed bundle. It does not write anything to the global scope. You can't use anything from cart.js unless you "rummage around" it for public access.
The correct solution would be to put ALL the code in cart.js, incl. and createApp and perhaps pass the settings there one way or another.
But if you really want to, in crat.js you can rummage around the functions you need globally, for example:
window.createApp = createApp;
window.store = store;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question