StencilJS: compile scss and copy to dist folder - stenciljs

My goal is to provide a css file in the distribution package which can be used by the consumer if needed.
For that I would like to create a kind of global scss file, but I want to avoid that this style is attached to each component + it also won't be used directly by the components. So for that I would like to create my-style.scss file somewhere in the /src folder.
What would be the best way to compile this file to my-style.css and copy it to the dist folder?

It is possible to specify a global style with Stencil. Simply add the globalStyle property to your stencil.config.js and provide the entry scss file. Your config should look something like this:
const sass = require('#stencil/sass');
exports.config = {
namespace: 'my-component-lib',
outputTargets:[
{
type: 'dist'
},
{
type: 'www',
serviceWorker: false
}
],
globalStyle: 'src/globals/app.scss',
plugins: [
sass()
]
};
exports.devServer = {
root: 'www',
watchGlob: '**/**'
}
The build will successfully compile the scss to dist/my-component-lib.css.

From the docs: https://stenciljs.com/docs/config/#copy
The copy config is an array of objects that defines any files or
folders that should be copied over to the build directory. Each object
in the array must include a src property which can be either an
absolute path, a relative path or a glob pattern. The config can also
provide an optional dest property which can be either an absolute
path or a path relative to the build directory. Also note that any
files within src/assets are automatically copied to www/assets for
convenience.
In the copy config below, it will copy the entire directory from
src/docs-content over to www/docs-content.
Within stencil.config.ts:
copy: [
{ src: 'docs-content' }
]
For example I am copying my css file from src to the build directory and it's totally standalone, e.g. https://github.com/BlazeUI/blaze/blob/master/packages/atoms/stencil.config.ts#L14

Related

Vite build gets path inside css file wrong if i set base to './'

i've set up a plain vanilla js Vite installation and changed the folder structure to include all my "working" files inside a "src" folder.
With the following rollup Option inside my vite.config.js file, the build process mimic my folder structure inside the dist folder as well.
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
let extType = assetInfo.name.split('.')[1];
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
extType = 'img';
}
if (/woff|woff2|ttf/i.test(extType)) {
extType = 'fonts';
}
return `assets/${extType}/[name]-[hash][extname]`;
},
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
},
},
Build process works as intended: all files are inside their specified folders and all links inside html & css files are rewritten correctly.
But as soon as i set 'base' to './' or '' inside my vite.config.js file and build the project the url links inside css files are corrupted. They are missing the path. Only base + filename are written. All urls inside html files are build correctly.
If i set the base to something like '/somename/' all urls (html&css) are build correctly.
How can i fix this? :)
Here is a stackblitz example, where the body background image shows this behaviour. https://stackblitz.com/edit/vitejs-vite-j6xd8y?file=dist/assets/css/index-1e183c12.css
This seems to be a bug in Vite 2 (as of 2.9.12). I recommend reporting the issue.
As a workaround, switch to Vite 3 (currently 3.0.0-beta.2), which has refactored the base configuration code and avoids the problem you observed:
npm i -D vite#beta
demo

How to uglify a js file upon building the vue project

I have a VUE2 project and in the public folder I created an iframe.html file that will be loaded in an iframe.
That iframe will also load a javascript.js file that I want encoded/uglified upon "npm run build" but I also want to be able to access it during dev.
How could I proceed?
Should this js file be placed inside the /src/assets/ folder and referenced from the iframe.html file? If yes, any advice?
Or should it stay in the public folder and upod the dist folder being built, encode it with something.
Any solution is welcome, thanks in advance!
Edit: Here are further details of how I use the iframe.
First, I'm referencing the .vue file in the router like so:
{
path: "/pages/:id/edit",
name: "edit",
component: () => import("../views/Edit.vue"),
},
Next, in the Edit.vue file, I add the iframe like so (note how it's referencing iframe.html that is in the public directory):
<iframe
id="iframe"
ref="iframe"
src="iframe.html"
/>
Next, in the iframe.html it's just normal html code, with this part including the javascript.js file (that actually is in the public folder as well for now)
<script src="javascript.js"></script>
You can explicitly include the .js file in your Webpack config by adding a rule for UglifyJsPlugin:
npm i -D uglifyjs-webpack-plugin
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
...
module.exports = {
optimization: {
minimizer: [
new UglifyJsPlugin({
include: /\/regex-for-file/,
minimize: true
})
]
}
...
};
In Vue.config.js, this might look like:
configureWebpack: {
plugins : [
new webpack.optimize.UglifyJsPlugin({
uglifyOptions: {
include: /\/regex-for-file/,
minimize: true
}
)}
]
}
Another option is to use uglify-es; this would allow you to get even more explicit by specifying from where to copy the file during build (assuming you might want the file located outside of src/):
npm i -D uglify-es // CopyWebpackPlugin ships w/ Vue's Webpack conf by default
const UglifyJS = require('uglify-es');
const { resolve } = require('path');
const resolveAbs = (dir) => resolve(__dirname, dir);
new CopyWebpackPlugin([
{
from: resolveAbs('../external'),
to: config.build.assetsSubDirectory
},
{
from: resolveAbs('../src/custom-build-path'),
to: config.build.assetsServerDirectory,
transform: (content, path) => UglifyJS.minify(content.toString()).code;
}
]),
To be able to access it during dev, you can include the path of the js file (relative to your Vue src directory) using the resolve.alias option in the config (so you don't need to deal with possibly ridiculous relative paths in your project). Finally, you can look into webpack's HTML plugin docs for info on importing an external index.html file if needed
I would recommend not putting it in static; by default it will not be minified and built if placed in that directory.
Update/edit: Sorry, I saw a 'uglify' and just assumed you wanted uglify js. As long as the script is in your Vue project directory (or otherwise specified in the Webpack config) the file should be minified during build. Vue has pretty smart defaults for Webpack; assuming the iframe is being referenced somewhere in the app i.e. the dependency graph it will be built.

Vue assets: change the files path at compilation

I am trying to find a way to change the file location at compilation.
In my project, some assets files are defined in public/aclib/. However I would like to get them in /public only in the compiled version as that's what the code uses.
Of course, I could just put those files directly in public/ in the project, but I'd like them to be in a subfolder for the project clarity.
Is this possible at all?
Thanks a lot for your help.
Search for copy-webpack-plugin
For example, in vue.config.js add property:
configureWebpack: {
new CopyPlugin({
patterns: [
{ from: "public/aclib", to: "public" }
],
}),
}

vue.js / electron How to list all folder names in public folder

I'm quite new in the Vue / electron...
I need to list all folder names that are in the /public directory.
Inside of these folders may be other subfolders with .pdf files.
So far i try it with:
require.context('#/../public/pdf/moreFolders', true, /^.*\.*$/)
but this seems more for displaying files inside a folder.
In the end, I want to show a menu that has the tree structure of that public folder.
Any idea of how I can display such a structure in Vue?
You can list files and read the content simply by using nodejs modules:
const fs = require('fs')
...
If the build should contain those files you have to add an entry in the vue.config.js
module.exports = {
transpileDependencies: [
'vuetify'
],
pluginOptions: {
electronBuilder: {
builderOptions: {
...
extraFiles: [
{
from: './data',
to: 'data',
filter: [
'**/*'
]
But that is only needed, if you want to use another directory, I would suggest. Public is always copied, as I know.

Remove hash from specific asset files in webpack

I'm using Vuejs in a new project and I've added some images to the assets folder. I need an image to be referenceable also in public/index.html, but when I build the project the resulting filename includes an hash.
For instance I've src/assets/logo.svg and after build I've dist/img/logo.e80b121e.svg, but I want dist/img/logo.svg
Is there a way to remove the hash only for a specific file? I need the hash in the other assets. I'm configuring webpack with vue.config.js.
If you're using the webpack config vue cli generated four you if you move your asset in the static folder it will not get the hash.
Items from assets are getting hashed.
You need to get out the assets files from the entry, assuming that you has chunckhash configured (something like this: output: {filename: "[name].[chunkhash].js"}).
You could copy directly from source and add the assets to index.html using some of this webpack plugins:
CopyWebpackPlugin
HtmlWebpackExternalsPlugin
example:
plugins: [
new HtmlWebpackExternalsPlugin({
externals: [
{
module: "#fortawesome/fontawesome-pro",
entry: "css/all.css",
},
],
}),
new CopyWebpackPlugin([
{
from: "./node_modules/#fortawesome/fontawesome-pro/webfonts",
to: "./vendor/#fortawesome/fontawesome-pro/webfonts/",
},
]),
]